GRASS 8 Programmer's Manual 8.6.0dev(2026)-55de52a352
Loading...
Searching...
No Matches
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 SPDX-FileCopyrightText: 2009-2010 Daniel Bundala
9 SPDX-FileCopyrightText: GRASS Development Team
10 SPDX-License-Identifier: GPL-2.0-or-later
11
12 \author Daniel Bundala (Google Summer of Code 2009)
13 */
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <grass/gis.h>
18#include <grass/vector.h>
19#include <grass/glocale.h>
20#include <grass/dbmi.h>
21#include <grass/neta.h>
22
23/*!
24 \brief Writes point
25
26 Writes GV_POINT to Out at the position of the node in <em>In</em>.
27
28 \param In pointer to Map_info structure (input vector map)
29 \param[in,out] Out pointer to Map_info structure (output vector map)
30 \param node node id
31 \param Cats pointer to line_cats structures
32 */
33void NetA_add_point_on_node(struct Map_info *In, struct Map_info *Out, int node,
34 struct line_cats *Cats)
35{
36 static struct line_pnts *Points;
37 double x, y, z;
38
39 Points = Vect_new_line_struct();
40 Vect_get_node_coor(In, node, &x, &y, &z);
41 Vect_reset_line(Points);
42 Vect_append_point(Points, x, y, z);
43 Vect_write_line(Out, GV_POINT, Points, Cats);
45}
46
47/* Returns the list of all points with the given category and field */
48/*void NetA_get_points_by_category(struct Map_info *In, int field, int cat,
49 * struct ilist *point_list)
50 * {
51 * int i, nlines;
52 * struct line_cats *Cats;
53 * Cats = Vect_new_cats_struct();
54 * Vect_get_num_lines(In);
55 * for(i=1;i<=nlines;i++){
56 * int type = Vect_read_line(In, NULL, Cats, i);
57 * if(type!=GV_POINT)continue;
58 * }
59 *
60 * Vect_destroy_cats_struct(Cats);
61 * }
62 */
63
64/*!
65 \brief Finds node
66
67 Find the node corresponding to each point in the point_list
68
69 \param In pointer to Map_info structure
70 \param point_list list of points (their ids)
71 */
73{
74 int i, node;
75 struct line_pnts *Points = Vect_new_line_struct();
76
77 for (i = 0; i < point_list->n_values; i++) {
78 /* Vect_get_line_nodes(In, point_list->value[i], &node, NULL); */
79 node =
80 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 */
105int 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
114 struct field_info *Fi;
115
116 Fi = Vect_get_field(In, layer);
117 if (Fi == NULL)
118 G_fatal_error(_("Database connection not defined for layer %d"), layer);
119
120 driver = db_start_driver_open_database(Fi->driver, Fi->database);
121 if (driver == NULL)
122 G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
123 Fi->database, Fi->driver);
124
125 nlines = Vect_get_num_lines(In);
127 for (i = 1; i <= nnodes; i++)
128 node_costs[i] = 0;
129
130 db_CatValArray_init(&vals);
131 int nvals =
132 db_select_CatValArray(driver, Fi->table, Fi->key, column, NULL, &vals);
133
136
137 if (nvals == -1)
138 return 0;
139
141 Points = Vect_new_line_struct();
142 for (i = 1; i <= nlines; i++) {
143 int type = Vect_read_line(In, Points, Cats, i);
144
145 if (type == GV_POINT) {
146 int node, cat;
147 double value;
148
149 if (!Vect_cat_get(Cats, layer, &cat))
150 continue;
151 Vect_get_line_nodes(In, i, &node, NULL);
152 if (db_CatValArray_get_value_double(&vals, cat, &value) == DB_OK) {
153 if (value < 0)
154 node_costs[node] = -1;
155 else
156 node_costs[node] = value * In->dgraph.cost_multip;
157 }
158 }
159 }
160
163 db_CatValArray_free(&vals);
164 return 1;
165}
166
167/*!
168 \brief Get list of nodes from varray
169
170 Returns the list of all nodes on features selected by varray.
171 nodes_to_features contains the index of a feature adjacent to each
172 node or -1 if no such feature specified by varray
173 exists. Nodes_to_features might be NULL, in which case it is left
174 uninitialised. Nodes_to_features will be wrong if several lines
175 connect to the same node.
176
177 \param map pointer to Map_info structure
178 \param varray pointer to varray structure
179 \param[out] nodes list of node ids
180 \param[out] nodes_to_features maps nodes to features
181 */
182void NetA_varray_to_nodes(struct Map_info *map, struct varray *varray,
183 struct ilist *nodes, int *nodes_to_features)
184{
185 int nlines, nnodes, i;
186 struct line_pnts *Points = Vect_new_line_struct();
187
188 nlines = Vect_get_num_lines(map);
191 for (i = 1; i <= nnodes; i++)
192 nodes_to_features[i] = -1;
193
194 for (i = 1; i <= nlines; i++) {
195 if (varray->c[i]) {
196 int type = Vect_read_line(map, Points, NULL, i);
197
198 if (type == GV_POINT) {
199 int node;
200
201 node = Vect_find_node(map, Points->x[0], Points->y[0],
202 Points->z[0], 0, 0);
203 if (node) {
204 Vect_list_append(nodes, node);
206 nodes_to_features[node] = i;
207 }
208 else
209 G_warning(_("Point %d is not connected!"), i);
210 }
211 else {
212 int node1, node2;
213
214 Vect_get_line_nodes(map, i, &node1, &node2);
219 }
220 }
221 }
223}
224
225/*!
226 \brief Initialize varray
227
228 \param In pointer to Map_info structure
229 \param layer layer number
230 \param mask_type ?
231 \param where where statement
232 \param cat ?
233 \param[out] pointer to varray structure
234
235 \return number of items set
236 \return -1 on error
237 */
238int NetA_initialise_varray(struct Map_info *In, int layer, int mask_type,
239 char *where, char *cat, struct varray **varray)
240{
241 int n, ni;
242
243 if (layer < 1)
244 G_fatal_error(_("'%s' must be > 0"), "layer");
245
246 n = Vect_get_num_lines(In);
248 ni = 0;
249
250 /* parse filter option and select appropriate lines */
251 if (where) {
252 if (cat)
253 G_warning(_("'where' and 'cats' parameters were supplied, cat will "
254 "be ignored"));
255 ni = Vect_set_varray_from_db(In, layer, where, mask_type, 1, *varray);
256 if (ni == -1) {
257 G_warning(_("Unable to load data from database"));
258 }
259 return ni;
260 }
261 else if (cat) {
262 ni = Vect_set_varray_from_cat_string(In, layer, cat, mask_type, 1,
263 *varray);
264 if (ni == -1) {
265 G_warning(_("Problem loading category values"));
266 }
267 return ni;
268 }
269 else { /* all features of given layer */
270 int i, cat;
271 int ltype; /* line type */
272 struct line_cats *Cats;
273
275
276 for (i = 1; i <= n; i++) {
277 ltype = Vect_read_line(In, NULL, Cats, i);
278
279 if (!(ltype & mask_type))
280 continue; /* is not specified type */
281
282 if (Vect_cat_get(Cats, layer, &cat)) {
283 (*varray)->c[i] = 1;
284 ni++;
285 }
286 }
288
289 return ni;
290 }
291}
#define NULL
Definition ccmath.h:32
Main header of GRASS DataBase Management Interface.
#define DB_OK
Definition dbmi.h:69
void db_CatValArray_free(dbCatValArray *)
Free allocated dbCatValArray.
Definition value.c:371
void db_CatValArray_init(dbCatValArray *)
Initialize dbCatValArray.
Definition value.c:359
int db_close_database_shutdown_driver(dbDriver *)
Close driver/database connection.
Definition db.c:58
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)
dbDriver * db_start_driver_open_database(const char *, const char *)
Open driver/database connection.
Definition db.c:25
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:75
int Vect_get_line_nodes(struct Map_info *, int, int *, int *)
Get line nodes.
Definition level_two.c:302
int Vect_get_node_coor(struct Map_info *, int, double *, double *, double *)
Get node coordinates.
Definition level_two.c:272
plus_t Vect_get_num_lines(struct Map_info *)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
Definition level_two.c:73
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:239
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.
struct field_info * Vect_get_field(struct Map_info *, int)
Get information about link to database (by layer number)
Definition field.c:508
int Vect_list_append(struct ilist *, int)
Append new item to the end of list if not yet present.
int Vect_read_line(struct Map_info *, struct line_pnts *, struct line_cats *, int)
Read vector feature (topological level required)
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
off_t Vect_write_line(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes a new feature.
void Vect_destroy_field_info(struct field_info *)
Free a struct field_info and all memory associated with it.
Definition field.c:626
plus_t Vect_get_num_nodes(struct Map_info *)
Get number of nodes in vector map.
Definition level_two.c:32
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:74
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:127
struct varray * Vect_new_varray(int)
Create new struct varray and allocate space for given number of items.
Definition array.c:34
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition line.c:43
int Vect_append_point(struct line_pnts *, double, double, double)
Appends one point to the end of a line.
Definition line.c:146
#define GV_POINT
Feature types used in memory on run time (may change)
#define _(str)
Definition glocale.h:10
Vector map info.
struct Graph_info dgraph
Graph info (built for network analysis)
Layer (old: field) information.
List of integers.
Definition gis.h:712
Feature category info.
int * cat
Array of categories.
Feature geometry info - coordinates.
double * y
Array of Y coordinates.
double * x
Array of X coordinates.
double * z
Array of Z coordinates.
Vector array.
int * c
Array.
void NetA_points_to_nodes(struct Map_info *In, struct ilist *point_list)
Finds node.
Definition utils.c:72
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:33
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:182
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:238
int NetA_get_node_costs(struct Map_info *In, int layer, char *column, int *node_costs)
Get node cost.
Definition utils.c:105