GRASS 8 Programmer's Manual 8.6.0dev(2026)-985dd2421b
Loading...
Searching...
No Matches
vector/Vlib/graph.c
Go to the documentation of this file.
1/*!
2 \file lib/vector/Vlib/graph.c
3
4 \brief Vector library - graph manipulation
5
6 Higher level functions for reading/writing/manipulating vectors.
7
8 \todo Vect_graph_free ( dglGraph_s *graph )
9
10 SPDX-FileCopyrightText: 2001-2009 GRASS Development Team
11 SPDX-License-Identifier: GPL-2.0-or-later
12
13 \author Radim Blazek
14 */
15
16#include <stdlib.h>
17#include <string.h>
18#include <grass/dbmi.h>
19#include <grass/vector.h>
20#include <grass/glocale.h>
21
22static int
23 From_node; /* from node set in SP and used by clipper for first arc */
24
25static int clipper(dglGraph_s *pgraph, dglSPClipInput_s *pargIn,
27{ /* caller's pointer */
28 dglInt32_t cost;
29 dglInt32_t from;
30
31 G_debug(3, "Net: clipper()");
32
33 from = dglNodeGet_Id(pgraph, pargIn->pnNodeFrom);
34
35 G_debug(3, " Edge = %d NodeFrom = %d NodeTo = %d edge cost = %d",
36 (int)dglEdgeGet_Id(pgraph, pargIn->pnEdge), (int)from,
37 (int)dglNodeGet_Id(pgraph, pargIn->pnNodeTo),
38 (int)pargOut->nEdgeCost);
39
40 if (from != From_node) { /* do not clip first */
41 if (dglGet_NodeAttrSize(pgraph) > 0) {
42 memcpy(&cost, dglNodeGet_Attr(pgraph, pargIn->pnNodeFrom),
43 sizeof(cost));
44 if (cost == -1) { /* closed, cannot go from this node except it is
45 'from' node */
46 G_debug(3, " closed node");
47 return 1;
48 }
49 else {
50 G_debug(3, " EdgeCost += %d (node)", (int)cost);
51 pargOut->nEdgeCost += cost;
52 }
53 }
54 }
55 else {
56 G_debug(3, " don't clip first node");
57 }
58
59 return 0;
60}
61
62/*!
63 \brief Initialize graph structure
64
65 \param graph pointer to graph structure
66 \param nodes_costs use node costs
67
68 \return void
69 */
71{
72 dglInt32_t opaqueset[16] = {360000, 0, 0, 0, 0, 0, 0, 0,
73 0, 0, 0, 0, 0, 0, 0, 0};
74
75 G_debug(3, "Vect_graph_init()");
76
77 if (nodes_costs)
79 opaqueset);
80 else
82 opaqueset);
83}
84
85/*!
86 \brief Build network graph.
87
88 Internal format for edge costs is integer, costs are multiplied
89 before conversion to int by 1000. Costs -1 for infinity i.e. arc
90 or node is closed and cannot be traversed.
91
92 \param graph pointer to graph structure
93
94 \return void
95 */
97{
98 int ret;
99
100 G_debug(3, "Vect_graph_build()");
101
103 if (ret < 0)
104 G_fatal_error(_("GngFlatten error"));
105}
106
107/*!
108 \brief Add edge to graph.
109
110 Internal format for edge costs is integer, costs are multiplied
111 before conversion to int by 1000. Costs -1 for infinity i.e. arc
112 or node is closed and cannot be traversed.
113
114 \param graph pointer to graph structure
115 \param from from node
116 \param to to node
117 \param costs costs value
118 \param id edge id
119
120 \return void
121 */
122void Vect_graph_add_edge(dglGraph_s *graph, int from, int to, double costs,
123 int id)
124{
125 int ret;
127
128 G_debug(3, "Vect_add_edge() from = %d to = %d, costs = %f, id = %d", from,
129 to, costs, id);
130
131 dglcosts = (dglInt32_t)costs * 1000;
132
134 (dglInt32_t)id);
135 if (ret < 0)
136 G_fatal_error(_("Unable to add network arc"));
137}
138
139/*!
140 \brief Set node costs
141
142 Internal format for edge costs is integer, costs are multiplied
143 before conversion to int by 1000. Costs -1 for infinity i.e. arc
144 or node is closed and cannot be traversed.
145
146 \param graph pointer to graph structure
147 \param node node id
148 \param costs costs value
149
150 \return void
151 */
153{
155
156 /* TODO: Not tested! */
157 G_debug(3, "Vect_graph_set_node_costs()");
158
159 dglcosts = (dglInt32_t)costs * 1000;
160
162}
163
164/*!
165 \brief Find shortest path.
166
167 Costs for 'from' and 'to' nodes are not considered (SP found even if
168 'from' or 'to' are 'closed' (costs = -1) and costs of these
169 nodes are not added to SP costs result.
170
171 \param graph pointer to graph structure
172 \param from from node
173 \param to to node
174 \param List list of line ids
175 \param cost costs value
176
177 \return number of segments
178 \return 0 is correct for from = to, or List == NULL ), ? sum of costs is
179 better return value, \return -1 destination unreachable
180 */
182 struct ilist *List, double *cost)
183{
184 int i, line, *pclip, cArc, nRet;
186 dglInt32_t nDistance;
187
188 G_debug(3, "Vect_graph_shortest_path(): from = %d, to = %d", from, to);
189
190 /* Note : if from == to dgl goes to nearest node and returns back (dgl
191 * feature) => check here for from == to */
192
193 if (List != NULL)
195
196 /* Check if from and to are identical, otherwise dglib returns path to
197 * nearest node and back! */
198 if (from == to) {
199 if (cost != NULL)
200 *cost = 0;
201 return 0;
202 }
203
204 From_node = from;
205
206 pclip = NULL;
207 if (List != NULL) {
209 (dglInt32_t)to, clipper, pclip, NULL);
210 }
211 else {
212 nRet = dglShortestDistance(graph, &nDistance, (dglInt32_t)from,
213 (dglInt32_t)to, clipper, pclip, NULL);
214 }
215
216 if (nRet == 0) {
217 if (cost != NULL)
218 *cost = PORT_DOUBLE_MAX;
219 return -1;
220 }
221 else if (nRet < 0) {
222 G_warning(_("dglShortestPath error: %s"), dglStrerror(graph));
223 return -1;
224 }
225
226 if (List != NULL) {
227 for (i = 0; i < pSPReport->cArc; i++) {
228 line = dglEdgeGet_Id(graph, pSPReport->pArc[i].pnEdge);
229 G_debug(2, "From %ld to %ld - cost %ld user %d distance %ld",
230 pSPReport->pArc[i].nFrom, pSPReport->pArc[i].nTo,
231 /* this is the cost from clip() */
232 dglEdgeGet_Cost(graph, pSPReport->pArc[i].pnEdge) / 1000,
233 line, pSPReport->pArc[i].nDistance);
234 Vect_list_append(List, line);
235 }
236 }
237
238 if (cost != NULL) {
239 if (List != NULL)
240 *cost = (double)pSPReport->nDistance / 1000;
241 else
242 *cost = (double)nDistance / 1000;
243 }
244
245 if (List != NULL) {
246 cArc = pSPReport->cArc;
248 }
249 else
250 cArc = 0;
251
252 return (cArc);
253}
#define NULL
Definition ccmath.h:32
Main header of GRASS DataBase Management Interface.
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
int Vect_list_append(struct ilist *, int)
Append new item to the end of list if not yet present.
int Vect_reset_list(struct ilist *)
Reset ilist structure.
#define PORT_DOUBLE_MAX
Limits for portable types.
Definition dig_defines.h:66
#define G_UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition gis.h:43
#define _(str)
Definition glocale.h:10
List of integers.
Definition gis.h:712
unsigned char dglByte_t
Definition type.h:23
long dglInt32_t
Definition type.h:24
void Vect_graph_init(dglGraph_s *graph, int nodes_costs)
Initialize graph structure.
void Vect_graph_add_edge(dglGraph_s *graph, int from, int to, double costs, int id)
Add edge to graph.
void Vect_graph_set_node_costs(dglGraph_s *graph, int node, double costs)
Set node costs.
void Vect_graph_build(dglGraph_s *graph)
Build network graph.
int Vect_graph_shortest_path(dglGraph_s *graph, int from, int to, struct ilist *List, double *cost)
Find shortest path.
dglInt32_t * dglGetNode(dglGraph_s *pGraph, dglInt32_t nNodeId)
void dglFreeSPReport(dglGraph_s *pgraph, dglSPReport_s *pSPReport)
int dglGet_NodeAttrSize(dglGraph_s *pgraph)
int dglAddEdge(dglGraph_s *pGraph, dglInt32_t nHead, dglInt32_t nTail, dglInt32_t nCost, dglInt32_t nEdge)
int dglShortestPath(dglGraph_s *pGraph, dglSPReport_s **ppReport, dglInt32_t nStart, dglInt32_t nDestination, dglSPClip_fn fnClip, void *pvClipArg, dglSPCache_s *pCache)
dglInt32_t dglEdgeGet_Id(dglGraph_s *pGraph, dglInt32_t *pnEdge)
void dglNodeSet_Attr(dglGraph_s *pGraph, dglInt32_t *pnNode, dglInt32_t *pnAttr)
int dglInitialize(dglGraph_s *pGraph, dglByte_t Version, dglInt32_t NodeAttrSize, dglInt32_t EdgeAttrSize, dglInt32_t *pOpaqueSet)
char * dglStrerror(dglGraph_s *pgraph)
int dglShortestDistance(dglGraph_s *pGraph, dglInt32_t *pnDistance, dglInt32_t nStart, dglInt32_t nDestination, dglSPClip_fn fnClip, void *pvClipArg, dglSPCache_s *pCache)
dglInt32_t * dglNodeGet_Attr(dglGraph_s *pGraph, dglInt32_t *pnNode)
int dglFlatten(dglGraph_s *pGraph)
dglInt32_t dglEdgeGet_Cost(dglGraph_s *pGraph, dglInt32_t *pnEdge)
dglInt32_t dglNodeGet_Id(dglGraph_s *pGraph, dglInt32_t *pnNode)