pgRouting  2.2
pgRouting extends the PostGIS / PostgreSQL geospatial database to provide geospatial routing functionality.
 All Classes Functions Variables Pages
edges_input.c
1 /*PGR-GNU*****************************************************************
2 File: edges_input.c
3 
4 Copyright (c) 2015 Celia Virginia Vergara Castillo
5 vicky_vergara@hotmail.com
6 
7 ------
8 
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 
23 ********************************************************************PGR-GNU*/
24 
25 // #define DEBUG
26 #include "./debug_macro.h"
27 #include "./pgr_types.h"
28 #include "./postgres_connection.h"
29 #include "./get_check_data.h"
30 #include "./edges_input.h"
31 #include "./time_msg.h"
32 
33 
34 
35 static
36 void pgr_fetch_edge(
37  HeapTuple *tuple,
38  TupleDesc *tupdesc,
39  Column_info_t info[5],
40  int64_t *default_id,
41  float8 default_rcost,
43  size_t *valid_edges) {
44  if (column_found(info[0].colNumber)) {
45  edge->id = pgr_SPI_getBigInt(tuple, tupdesc, info[0]);
46  } else {
47  edge->id = *default_id;
48  ++(*default_id);
49  }
50 
51  edge->source = pgr_SPI_getBigInt(tuple, tupdesc, info[1]);
52  edge->target = pgr_SPI_getBigInt(tuple, tupdesc, info[2]);
53  edge->cost = pgr_SPI_getFloat8(tuple, tupdesc, info[3]);
54 
55  if (column_found(info[4].colNumber)) {
56  edge->reverse_cost = pgr_SPI_getFloat8(tuple, tupdesc, info[4]);
57  } else {
58  edge->reverse_cost = default_rcost;
59  }
60 
61  *valid_edges = edge->cost < 0? *valid_edges: *valid_edges + 1;
62  *valid_edges = edge->reverse_cost < 0? *valid_edges: *valid_edges + 1;
63 }
64 
65 static
66 void
67 get_data_5_columns(
68  char *sql,
69  pgr_edge_t **edges,
70  size_t *totalTuples,
71  bool ignore_id) {
72  clock_t start_t = clock();
73 
74  const int tuple_limit = 1000000;
75 
76  size_t ntuples;
77  size_t total_tuples;
78  size_t valid_edges;
79 
80  Column_info_t info[5];
81 
82  int i;
83  for (i = 0; i < 5; ++i) {
84  info[i].colNumber = -1;
85  info[i].type = 0;
86  info[i].strict = true;
87  info[i].eType = ANY_INTEGER;
88  }
89  info[0].name = strdup("id");
90  info[1].name = strdup("source");
91  info[2].name = strdup("target");
92  info[3].name = strdup("cost");
93  info[4].name = strdup("reverse_cost");
94 
95  info[0].strict = !ignore_id;
96  info[4].strict = false;
97 
98  info[3].eType = ANY_NUMERICAL;
99  info[4].eType = ANY_NUMERICAL;
100 
101 
102  void *SPIplan;
103  SPIplan = pgr_SPI_prepare(sql);
104 
105  Portal SPIportal;
106  SPIportal = pgr_SPI_cursor_open(SPIplan);
107 
108 
109  bool moredata = TRUE;
110  (*totalTuples) = total_tuples = valid_edges = 0;
111 
112 
113  int64_t default_id = 0;
114  while (moredata == TRUE) {
115  SPI_cursor_fetch(SPIportal, TRUE, tuple_limit);
116  if (total_tuples == 0)
117  pgr_fetch_column_info(info, 5);
118 
119  ntuples = SPI_processed;
120  total_tuples += ntuples;
121 
122  if (ntuples > 0) {
123  if ((*edges) == NULL)
124  (*edges) = (pgr_edge_t *)palloc0(total_tuples * sizeof(pgr_edge_t));
125  else
126  (*edges) = (pgr_edge_t *)repalloc((*edges), total_tuples * sizeof(pgr_edge_t));
127 
128  if ((*edges) == NULL) {
129  elog(ERROR, "Out of memory");
130  }
131 
132  size_t t;
133  SPITupleTable *tuptable = SPI_tuptable;
134  TupleDesc tupdesc = SPI_tuptable->tupdesc;
135  PGR_DBG("processing %d edge tupĺes", ntuples);
136 
137  for (t = 0; t < ntuples; t++) {
138  HeapTuple tuple = tuptable->vals[t];
139  pgr_fetch_edge(&tuple, &tupdesc, info,
140  &default_id, -1,
141  &(*edges)[total_tuples - ntuples + t],
142  &valid_edges);
143  }
144  SPI_freetuptable(tuptable);
145  } else {
146  moredata = FALSE;
147  }
148  }
149 
150 
151  if (total_tuples == 0 || valid_edges == 0) {
152  (*totalTuples) = 0;
153  PGR_DBG("NO edges");
154  return;
155  }
156 
157 
158  (*totalTuples) = total_tuples;
159  PGR_DBG("Finish reading %ld edges, %ld", total_tuples, (*totalTuples));
160  time_msg(" reading Edges", start_t, clock());
161 }
162 
163 void
164 pgr_get_data_5_columns(
165  char *sql,
166  pgr_edge_t **edges,
167  size_t *totalTuples) {
168  bool ignore_id = false;
169  get_data_5_columns(sql, edges, totalTuples, ignore_id);
170 }
171 
172 void
173 pgr_get_data_4_columns(
174  char *sql,
175  pgr_edge_t **edges,
176  size_t *totalTuples) {
177  bool ignore_id = true;
178  get_data_5_columns(sql, edges, totalTuples, ignore_id);
179 }