GRASS GIS 8 Programmer's Manual  8.2.2dev(2023)-3d2c704037
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 /*!
26  \brief Writes point
27 
28  Writes GV_POINT to Out at the position of the node in <em>In</em>.
29 
30  \param In pointer to Map_info structure (input vector map)
31  \param[in,out] Out pointer to Map_info structure (output vector map)
32  \param node node id
33  \param Cats pointer to line_cats structures
34  */
35 void NetA_add_point_on_node(struct Map_info *In, struct Map_info *Out,
36  int node, struct line_cats *Cats)
37 {
38  static struct line_pnts *Points;
39  double x, y, z;
40 
41  Points = Vect_new_line_struct();
42  Vect_get_node_coor(In, node, &x, &y, &z);
43  Vect_reset_line(Points);
44  Vect_append_point(Points, x, y, z);
45  Vect_write_line(Out, GV_POINT, Points, Cats);
47 }
48 
49 /* Returns the list of all points with the given category and field */
50 /*void NetA_get_points_by_category(struct Map_info *In, int field, int cat, 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 = Vect_find_node(In, Points->x[0], Points->y[0], Points->z[0], 0, 0);
81  point_list->value[i] = node;
82  }
84 }
85 
86 /*!
87  \brief Get node cost
88 
89  For each node in the map, finds the category of the point on it (if
90  there is any) and stores the value associated with this category in
91  the array node_costs. If there is no point with a category,
92  node_costs=0.
93 
94  node_costs are multiplied by the graph's cost multiplier and
95  truncated to integers (as is done in Vect_net_build_graph)
96 
97  \param In pointer to Map_info structure
98  \param layer layer number
99  \param column name of column
100  \param[out] node_costs list of node costs
101 
102  \returns 1 on success
103  \return 0 on failure
104  */
105 int NetA_get_node_costs(struct Map_info *In, int layer, char *column,
106  int *node_costs)
107 {
108  int i, nlines, nnodes;
109  dbCatValArray vals;
110  struct line_cats *Cats;
111  struct line_pnts *Points;
112 
113  dbDriver *driver;
114  struct field_info *Fi;
115 
116  Fi = Vect_get_field(In, layer);
117  driver = db_start_driver_open_database(Fi->driver, Fi->database);
118  if (driver == NULL)
119  G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
120  Fi->database, Fi->driver);
121 
122  nlines = Vect_get_num_lines(In);
123  nnodes = Vect_get_num_nodes(In);
124  Cats = Vect_new_cats_struct();
125  Points = Vect_new_line_struct();
126  for (i = 1; i <= nnodes; i++)
127  node_costs[i] = 0;
128 
129  db_CatValArray_init(&vals);
130 
131  if (db_select_CatValArray(driver, Fi->table, Fi->key, column, NULL, &vals)
132  == -1)
133  return 0;
134  for (i = 1; i <= nlines; i++) {
135  int type = Vect_read_line(In, Points, Cats, i);
136 
137  if (type == GV_POINT) {
138  int node, cat;
139  double value;
140 
141  if (!Vect_cat_get(Cats, layer, &cat))
142  continue;
143  Vect_get_line_nodes(In, i, &node, NULL);
144  if (db_CatValArray_get_value_double(&vals, cat, &value) == DB_OK) {
145  if (value < 0)
146  node_costs[node] = -1;
147  else
148  node_costs[node] = value * In->dgraph.cost_multip;
149  }
150  }
151  }
152 
154  db_CatValArray_free(&vals);
156  return 1;
157 }
158 
159 /*!
160  \brief Get list of nodes from varray
161 
162  Returns the list of all nodes on features selected by varray.
163  nodes_to_features contains the index of a feature adjacent to each
164  node or -1 if no such feature specified by varray
165  exists. Nodes_to_features might be NULL, in which case it is left
166  unitialised. Nodes_to_features will be wrong if several lines connect
167  to the same node.
168 
169  \param map pointer to Map_info structure
170  \param varray pointer to varray structure
171  \param[out] nodes list of node ids
172  \param[out] nodes_to_features maps nodes to features
173  */
174 void NetA_varray_to_nodes(struct Map_info *map, struct varray *varray,
175  struct ilist *nodes, int *nodes_to_features)
176 {
177  int nlines, nnodes, i;
178  struct line_pnts *Points = Vect_new_line_struct();
179 
180  nlines = Vect_get_num_lines(map);
181  nnodes = Vect_get_num_nodes(map);
182  if (nodes_to_features)
183  for (i = 1; i <= nnodes; i++)
184  nodes_to_features[i] = -1;
185 
186  for (i = 1; i <= nlines; i++) {
187  if (varray->c[i]) {
188  int type = Vect_read_line(map, Points, NULL, i);
189 
190  if (type == GV_POINT) {
191  int node;
192 
193  node = Vect_find_node(map, Points->x[0], Points->y[0], Points->z[0], 0, 0);
194  if (node) {
195  Vect_list_append(nodes, node);
196  if (nodes_to_features)
197  nodes_to_features[node] = i;
198  }
199  else
200  G_warning(_("Point %d is not connected!"), i);
201  }
202  else {
203  int node1, node2;
204 
205  Vect_get_line_nodes(map, i, &node1, &node2);
206  Vect_list_append(nodes, node1);
207  Vect_list_append(nodes, node2);
208  if (nodes_to_features)
209  nodes_to_features[node1] = nodes_to_features[node2] = i;
210  }
211  }
212  }
213  Vect_destroy_line_struct(Points);
214 }
215 
216 /*!
217  \brief Initialize varray
218 
219  \param In pointer to Map_info structure
220  \param layer layer number
221  \param mask_type ?
222  \param where where statement
223  \param cat ?
224  \param[out] pointer to varray structure
225 
226  \return number of items set
227  \return -1 on error
228  */
229 int NetA_initialise_varray(struct Map_info *In, int layer, int mask_type,
230  char *where, char *cat, struct varray **varray)
231 {
232  int n, ni;
233 
234  if (layer < 1)
235  G_fatal_error(_("'%s' must be > 0"), "layer");
236 
237  n = Vect_get_num_lines(In);
238  *varray = Vect_new_varray(n);
239  ni = 0;
240 
241  /* parse filter option and select appropriate lines */
242  if (where) {
243  if (cat)
244  G_warning(_("'where' and 'cats' parameters were supplied, cat will be ignored"));
245  ni = Vect_set_varray_from_db(In, layer, where, mask_type, 1, *varray);
246  if (ni == -1) {
247  G_warning(_("Unable to load data from database"));
248  }
249  return ni;
250  }
251  else if (cat) {
252  ni = Vect_set_varray_from_cat_string(In, layer, cat, mask_type, 1, *varray);
253  if (ni == -1) {
254  G_warning(_("Problem loading category values"));
255  }
256  return ni;
257  }
258  else { /* all features of given layer */
259  int i, cat;
260  int ltype; /* line type */
261  struct line_cats *Cats;
262 
263  Cats = Vect_new_cats_struct();
264 
265  for (i = 1; i <= n; i++) {
266  ltype = Vect_read_line(In, NULL, Cats, i);
267 
268  if (!(ltype & mask_type))
269  continue; /* is not specified type */
270 
271  if (Vect_cat_get(Cats, layer, &cat)) {
272  (*varray)->c[i] = 1;
273  ni++;
274  }
275  }
277 
278  return ni;
279  }
280 }
int Vect_set_varray_from_cat_string(const struct Map_info *, int, const char *, int, int, struct varray *)
Set values in &#39;varray&#39; to &#39;value&#39; from category string.
Definition: array.c:82
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void db_CatValArray_init(dbCatValArray *)
Initialize dbCatValArray.
Definition: value.c:361
plus_t Vect_get_num_nodes(const struct Map_info *)
Get number of nodes in vector map.
Definition: level_two.c:34
plus_t Vect_get_num_lines(const struct Map_info *)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
Definition: level_two.c:74
char * table
Name of DB table.
Definition: dig_structs.h:155
int n_values
Number of values in the list.
Definition: gis.h:709
dbDriver * db_start_driver_open_database(const char *, const char *)
Open driver/database connection.
Definition: db.c:28
Vector array.
Definition: dig_structs.h:1779
#define NULL
Definition: ccmath.h:32
#define x
#define GV_POINT
Feature types used in memory on run time (may change)
Definition: dig_defines.h:182
int db_close_database_shutdown_driver(dbDriver *)
Close driver/database connection.
Definition: db.c:62
struct field_info * Vect_get_field(const struct Map_info *, int)
Get information about link to database (by layer number)
Definition: field.c:507
char * database
Definition: dig_structs.h:151
Feature category info.
Definition: dig_structs.h:1702
int Vect_get_node_coor(const struct Map_info *, int, double *, double *, double *)
Get node coordinates.
Definition: level_two.c:278
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:174
Layer (old: field) information.
Definition: dig_structs.h:134
struct Graph_info dgraph
Graph info (built for network analysis)
Definition: dig_structs.h:1398
double * x
Array of X coordinates.
Definition: dig_structs.h:1680
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:229
Feature geometry info - coordinates.
Definition: dig_structs.h:1675
int NetA_get_node_costs(struct Map_info *In, int layer, char *column, int *node_costs)
Get node cost.
Definition: utils.c:105
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition: line.c:45
void Vect_destroy_cats_struct(struct line_cats *)
Frees all memory associated with line_cats structure, including the struct itself.
int Vect_find_node(struct Map_info *, double, double, double, double, int)
Find the nearest node.
off_t Vect_write_line(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes a new feature.
int Vect_append_point(struct line_pnts *, double, double, double)
Appends one point to the end of a line.
Definition: line.c:149
const struct driver * driver
Definition: driver/init.c:25
int db_CatValArray_get_value_double(dbCatValArray *, int, double *)
Find value (double) by key.
struct varray * Vect_new_varray(int)
Create new struct varray and allocate space for given number of items.
Definition: array.c:41
int Vect_get_line_nodes(const struct Map_info *, int, int *, int *)
Get line nodes.
Definition: level_two.c:307
Vector map info.
Definition: dig_structs.h:1259
double * y
Array of Y coordinates.
Definition: dig_structs.h:1684
char * driver
Name of DB driver (&#39;sqlite&#39;, &#39;dbf&#39;, ...)
Definition: dig_structs.h:147
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
void NetA_points_to_nodes(struct Map_info *In, struct ilist *point_list)
Finds node.
Definition: utils.c:73
void db_CatValArray_free(dbCatValArray *)
Free allocated dbCatValArray.
Definition: value.c:373
int Vect_list_append(struct ilist *, int)
Append new item to the end of list if not yet present.
void G_warning(const char *,...) __attribute__((format(printf
int cost_multip
Edge and node costs multiplicator.
Definition: dig_structs.h:1250
double * z
Array of Z coordinates.
Definition: dig_structs.h:1688
#define _(str)
Definition: glocale.h:10
List of integers.
Definition: gis.h:700
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:35
int * value
Array of values.
Definition: gis.h:705
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)
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_read_line(const struct Map_info *, struct line_pnts *, struct line_cats *, int)
Read vector feature (topological level required)
int Vect_cat_get(const struct line_cats *, int, int *)
Get first found category of given field.
void Vect_reset_line(struct line_pnts *)
Reset line.
Definition: line.c:130
int Vect_set_varray_from_db(const struct Map_info *, int, const char *, int, int, struct varray *)
Set values in &#39;varray&#39; to &#39;value&#39; from DB (where statement)
Definition: array.c:249
#define DB_OK
Definition: dbmi.h:71
int * c
Array.
Definition: dig_structs.h:1791
char * key
Name of key column (usually &#39;cat&#39;)
Definition: dig_structs.h:159