pgRouting
pgRouting extends the PostGIS / PostgreSQL geospatial database to provide geospatial routing functionality.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
edges_input.c
Go to the documentation of this file.
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 static
35  HeapTuple *tuple,
36  TupleDesc *tupdesc,
37  Column_info_t info[5],
38  int64_t *default_id,
40  size_t *valid_edges) {
41  if (column_found(info[0].colNumber)) {
42  edge->id = pgr_SPI_getBigInt(tuple, tupdesc, info[0]);
43  } else {
44  edge->id = *default_id;
45  ++(*default_id);
46  }
47 
48  edge->source = pgr_SPI_getBigInt(tuple, tupdesc, info[1]);
49  edge->target = pgr_SPI_getBigInt(tuple, tupdesc, info[2]);
50  edge->going = pgr_SPI_getFloat8(tuple, tupdesc, info[3]) > 0 ? true : false;
51  edge->coming = (column_found(info[4].colNumber) && pgr_SPI_getFloat8(tuple, tupdesc, info[4]) > 0) ? true : false;
52 
53  (*valid_edges)++;
54 }
55 
56 static
58  HeapTuple *tuple,
59  TupleDesc *tupdesc,
60  Column_info_t info[5],
61  int64_t *default_id,
62  float8 default_rcost,
64  size_t *valid_edges) {
65  if (column_found(info[0].colNumber)) {
66  edge->id = pgr_SPI_getBigInt(tuple, tupdesc, info[0]);
67  } else {
68  edge->id = *default_id;
69  ++(*default_id);
70  }
71 
72  edge->source = pgr_SPI_getBigInt(tuple, tupdesc, info[1]);
73  edge->target = pgr_SPI_getBigInt(tuple, tupdesc, info[2]);
74  edge->cost = pgr_SPI_getFloat8(tuple, tupdesc, info[3]);
75 
76  if (column_found(info[4].colNumber)) {
77  edge->reverse_cost = pgr_SPI_getFloat8(tuple, tupdesc, info[4]);
78  } else {
79  edge->reverse_cost = default_rcost;
80  }
81 
82  *valid_edges = edge->cost < 0? *valid_edges: *valid_edges + 1;
83  *valid_edges = edge->reverse_cost < 0? *valid_edges: *valid_edges + 1;
84 }
85 
86 static
88  HeapTuple *tuple,
89  TupleDesc *tupdesc,
90  Column_info_t info[9],
91  int64_t *default_id,
92  float8 default_rcost,
94  size_t *valid_edges,
95  bool normal) {
96  if (column_found(info[0].colNumber)) {
97  edge->id = pgr_SPI_getBigInt(tuple, tupdesc, info[0]);
98  } else {
99  edge->id = *default_id;
100  ++(*default_id);
101  }
102 
103  if (normal) {
104  edge->source = pgr_SPI_getBigInt(tuple, tupdesc, info[1]);
105  edge->target = pgr_SPI_getBigInt(tuple, tupdesc, info[2]);
106  } else {
107  edge->target = pgr_SPI_getBigInt(tuple, tupdesc, info[1]);
108  edge->source = pgr_SPI_getBigInt(tuple, tupdesc, info[2]);
109  }
110  edge->cost = pgr_SPI_getFloat8(tuple, tupdesc, info[3]);
111 
112  if (column_found(info[4].colNumber)) {
113  edge->reverse_cost = pgr_SPI_getFloat8(tuple, tupdesc, info[4]);
114  } else {
115  edge->reverse_cost = default_rcost;
116  }
117 
118  edge->x1 = pgr_SPI_getFloat8(tuple, tupdesc, info[5]);
119  edge->y1 = pgr_SPI_getFloat8(tuple, tupdesc, info[6]);
120  edge->x2 = pgr_SPI_getFloat8(tuple, tupdesc, info[7]);
121  edge->y2 = pgr_SPI_getFloat8(tuple, tupdesc, info[8]);
122 
123  *valid_edges = edge->cost < 0? *valid_edges: *valid_edges + 1;
124  *valid_edges = edge->reverse_cost < 0? *valid_edges: *valid_edges + 1;
125 }
126 
127 static
128 void
130  char *sql,
132  size_t *total_edges,
133  bool normal) {
134  clock_t start_t = clock();
135 
136  const int tuple_limit = 1000000;
137 
138  size_t ntuples;
139  size_t total_tuples;
140  size_t valid_edges;
141 
142  Column_info_t info[9];
143 
144  info[0].name = strdup("id");
145  info[1].name = strdup("source");
146  info[2].name = strdup("target");
147  info[3].name = strdup("cost");
148  info[4].name = strdup("reverse_cost");
149  info[5].name = strdup("x1");
150  info[6].name = strdup("y1");
151  info[7].name = strdup("x2");
152  info[8].name = strdup("y2");
153 
154  int i;
155  for (i = 0; i < 3; ++i) {
156  info[i].colNumber = -1;
157  info[i].type = 0;
158  info[i].strict = true;
159  info[i].eType = ANY_INTEGER;
160  }
161  for (i = 3; i < 9; ++i) {
162  info[i].colNumber = -1;
163  info[i].type = 0;
164  info[i].strict = true;
165  info[i].eType = ANY_NUMERICAL;
166  }
167  /*
168  * reverse_cost is optional
169  */
170  info[4].strict = false;
171 
172 
173  void *SPIplan;
174  SPIplan = pgr_SPI_prepare(sql);
175 
176  Portal SPIportal;
177  SPIportal = pgr_SPI_cursor_open(SPIplan);
178 
179 
180  bool moredata = TRUE;
181  (*total_edges) = total_tuples = valid_edges = 0;
182 
183 
184  int64_t default_id = 0;
185  while (moredata == TRUE) {
186  SPI_cursor_fetch(SPIportal, TRUE, tuple_limit);
187  if (total_tuples == 0)
188  pgr_fetch_column_info(info, 9);
189 
190  ntuples = SPI_processed;
191  total_tuples += ntuples;
192 
193  if (ntuples > 0) {
194  if ((*edges) == NULL)
195  (*edges) = (Pgr_edge_xy_t *)
196  palloc0(total_tuples * sizeof(Pgr_edge_xy_t));
197  else
198  (*edges) = (Pgr_edge_xy_t *)
199  repalloc((*edges), total_tuples * sizeof(Pgr_edge_xy_t));
200 
201  if ((*edges) == NULL) {
202  elog(ERROR, "Out of memory");
203  }
204 
205  size_t t;
206  SPITupleTable *tuptable = SPI_tuptable;
207  TupleDesc tupdesc = SPI_tuptable->tupdesc;
208  PGR_DBG("processing %ld edge tupĺes", ntuples);
209 
210  for (t = 0; t < ntuples; t++) {
211  HeapTuple tuple = tuptable->vals[t];
212  fetch_edge_with_xy(&tuple, &tupdesc, info,
213  &default_id, -1,
214  &(*edges)[total_tuples - ntuples + t],
215  &valid_edges, normal);
216  }
217  SPI_freetuptable(tuptable);
218  } else {
219  moredata = FALSE;
220  }
221  }
222 
223 
224  if (total_tuples == 0 || valid_edges == 0) {
225  PGR_DBG("NO edges found");
226  return;
227  }
228 
229  (*total_edges) = total_tuples;
230  PGR_DBG("Finish reading %ld edges, %ld", total_tuples, (*total_edges));
231  time_msg(" reading Edges with xy", start_t, clock());
232 }
233 
234 
235 
236 static
237 void
239  char *sql,
240  pgr_edge_t **edges,
241  size_t *totalTuples,
242  bool ignore_id) {
243  clock_t start_t = clock();
244 
245  const int tuple_limit = 1000000;
246 
247  size_t ntuples;
248  size_t total_tuples;
249  size_t valid_edges;
250 
251  Column_info_t info[5];
252 
253  int i;
254  for (i = 0; i < 5; ++i) {
255  info[i].colNumber = -1;
256  info[i].type = 0;
257  info[i].strict = true;
258  info[i].eType = ANY_INTEGER;
259  }
260  info[0].name = strdup("id");
261  info[1].name = strdup("source");
262  info[2].name = strdup("target");
263  info[3].name = strdup("cost");
264  info[4].name = strdup("reverse_cost");
265 
266  info[0].strict = !ignore_id;
267  info[4].strict = false;
268 
269  info[3].eType = ANY_NUMERICAL;
270  info[4].eType = ANY_NUMERICAL;
271 
272 
273  void *SPIplan;
274  SPIplan = pgr_SPI_prepare(sql);
275 
276  Portal SPIportal;
277  SPIportal = pgr_SPI_cursor_open(SPIplan);
278 
279 
280  bool moredata = TRUE;
281  (*totalTuples) = total_tuples = valid_edges = 0;
282 
283 
284  int64_t default_id = 0;
285  while (moredata == TRUE) {
286  SPI_cursor_fetch(SPIportal, TRUE, tuple_limit);
287  if (total_tuples == 0)
288  pgr_fetch_column_info(info, 5);
289 
290  ntuples = SPI_processed;
291  total_tuples += ntuples;
292 
293  if (ntuples > 0) {
294  if ((*edges) == NULL)
295  (*edges) = (pgr_edge_t *)
296  palloc0(total_tuples * sizeof(pgr_edge_t));
297  else
298  (*edges) = (pgr_edge_t *)
299  repalloc((*edges), total_tuples * sizeof(pgr_edge_t));
300 
301  if ((*edges) == NULL) {
302  elog(ERROR, "Out of memory");
303  }
304 
305  size_t t;
306  SPITupleTable *tuptable = SPI_tuptable;
307  TupleDesc tupdesc = SPI_tuptable->tupdesc;
308  PGR_DBG("processing %ld edge tupĺes", ntuples);
309 
310  for (t = 0; t < ntuples; t++) {
311  HeapTuple tuple = tuptable->vals[t];
312  fetch_edge(&tuple, &tupdesc, info,
313  &default_id, -1,
314  &(*edges)[total_tuples - ntuples + t],
315  &valid_edges);
316  }
317  SPI_freetuptable(tuptable);
318  } else {
319  moredata = FALSE;
320  }
321  }
322 
323 
324  if (total_tuples == 0 || valid_edges == 0) {
325  (*totalTuples) = 0;
326  PGR_DBG("NO edges");
327  return;
328  }
329 
330  (*totalTuples) = total_tuples;
331  PGR_DBG("Finish reading %ld edges, %ld", total_tuples, (*totalTuples));
332  time_msg(" reading Edges", start_t, clock());
333 }
334 
335 static
336 void
338  char *sql,
339  pgr_edge_t **edges,
340  size_t *totalTuples,
341  bool ignore_id) {
342  clock_t start_t = clock();
343 
344  const int tuple_limit = 1000000;
345 
346  size_t ntuples;
347  size_t total_tuples;
348  size_t valid_edges;
349 
350  Column_info_t info[5];
351 
352  int i;
353  for (i = 0; i < 5; ++i) {
354  info[i].colNumber = -1;
355  info[i].type = 0;
356  info[i].strict = true;
357  info[i].eType = ANY_INTEGER;
358  }
359  info[0].name = strdup("id");
360  info[1].name = strdup("source");
361  info[2].name = strdup("target");
362  info[3].name = strdup("capacity");
363  info[4].name = strdup("reverse_capacity");
364 
365  info[0].strict = !ignore_id;
366  info[4].strict = false;
367 
368  void *SPIplan;
369  SPIplan = pgr_SPI_prepare(sql);
370 
371  Portal SPIportal;
372  SPIportal = pgr_SPI_cursor_open(SPIplan);
373 
374 
375  bool moredata = TRUE;
376  (*totalTuples) = total_tuples = valid_edges = 0;
377 
378 
379  int64_t default_id = 0;
380  while (moredata == TRUE) {
381  SPI_cursor_fetch(SPIportal, TRUE, tuple_limit);
382  if (total_tuples == 0)
383  pgr_fetch_column_info(info, 5);
384 
385  ntuples = SPI_processed;
386  total_tuples += ntuples;
387 
388  if (ntuples > 0) {
389  if ((*edges) == NULL)
390  (*edges) = (pgr_edge_t *)palloc0(total_tuples * sizeof(pgr_flow_t));
391  else
392  (*edges) = (pgr_edge_t *)repalloc((*edges), total_tuples * sizeof(pgr_flow_t));
393 
394  if ((*edges) == NULL) {
395  elog(ERROR, "Out of memory");
396  }
397 
398  size_t t;
399  SPITupleTable *tuptable = SPI_tuptable;
400  TupleDesc tupdesc = SPI_tuptable->tupdesc;
401  PGR_DBG("processing %lu edge tupĺes", ntuples);
402 
403  for (t = 0; t < ntuples; t++) {
404  HeapTuple tuple = tuptable->vals[t];
405  fetch_edge(&tuple, &tupdesc, info,
406  &default_id, -1,
407  &(*edges)[total_tuples - ntuples + t],
408  &valid_edges);
409  }
410  SPI_freetuptable(tuptable);
411  } else {
412  moredata = FALSE;
413  }
414  }
415 
416 
417  if (total_tuples == 0 || valid_edges == 0) {
418  (*totalTuples) = 0;
419  PGR_DBG("NO edges");
420  return;
421  }
422 
423  (*totalTuples) = total_tuples;
424  PGR_DBG("Finish reading %ld edges, %ld", total_tuples, (*totalTuples));
425  time_msg(" reading Edges", start_t, clock());
426 }
427 
428 static
429 void
431  char *sql,
433  size_t *totalTuples,
434  bool ignore_id) {
435  clock_t start_t = clock();
436 
437  const int tuple_limit = 1000000;
438 
439  size_t ntuples;
440  size_t total_tuples;
441  size_t valid_edges;
442 
443  Column_info_t info[5];
444 
445  int i;
446  for (i = 0; i < 5; ++i) {
447  info[i].colNumber = -1;
448  info[i].type = 0;
449  info[i].strict = true;
450  info[i].eType = ANY_INTEGER;
451  }
452  info[0].name = strdup("id");
453  info[1].name = strdup("source");
454  info[2].name = strdup("target");
455  info[3].name = strdup("going");
456  info[4].name = strdup("coming");
457 
458  info[0].strict = !ignore_id;
459  info[4].strict = false;
460 
461  info[3].eType = ANY_NUMERICAL;
462  info[4].eType = ANY_NUMERICAL;
463 
464 
465  void *SPIplan;
466  SPIplan = pgr_SPI_prepare(sql);
467 
468  Portal SPIportal;
469  SPIportal = pgr_SPI_cursor_open(SPIplan);
470 
471 
472  bool moredata = TRUE;
473  (*totalTuples) = total_tuples = valid_edges = 0;
474 
475 
476  int64_t default_id = 0;
477  while (moredata == TRUE) {
478  SPI_cursor_fetch(SPIportal, TRUE, tuple_limit);
479  if (total_tuples == 0)
480  pgr_fetch_column_info(info, 5);
481 
482  ntuples = SPI_processed;
483  total_tuples += ntuples;
484 
485  if (ntuples > 0) {
486  if ((*edges) == NULL)
487  (*edges) = (pgr_basic_edge_t *)palloc0(total_tuples * sizeof(pgr_basic_edge_t));
488  else
489  (*edges) = (pgr_basic_edge_t *)repalloc((*edges), total_tuples * sizeof(pgr_basic_edge_t));
490 
491  if ((*edges) == NULL) {
492  elog(ERROR, "Out of memory");
493  }
494 
495  size_t t;
496  SPITupleTable *tuptable = SPI_tuptable;
497  TupleDesc tupdesc = SPI_tuptable->tupdesc;
498  PGR_DBG("processing %ld edge tupĺes", ntuples);
499 
500  for (t = 0; t < ntuples; t++) {
501  HeapTuple tuple = tuptable->vals[t];
502  fetch_basic_edge(&tuple, &tupdesc, info,
503  &default_id,
504  &(*edges)[total_tuples - ntuples + t],
505  &valid_edges);
506  }
507  SPI_freetuptable(tuptable);
508  } else {
509  moredata = FALSE;
510  }
511  }
512 
513 
514  if (total_tuples == 0 || valid_edges == 0) {
515  (*totalTuples) = 0;
516  PGR_DBG("NO edges");
517  return;
518  }
519 
520  (*totalTuples) = total_tuples;
521  PGR_DBG("Finish reading %ld edges, %ld", total_tuples, (*totalTuples));
522  time_msg(" reading Edges", start_t, clock());
523 }
524 
525 void
527  char *sql,
528  pgr_edge_t **edges,
529  size_t *total_edges) {
530  bool ignore_id = false;
531  get_edges_flow(sql, edges, total_edges, ignore_id);
532 }
533 
534 void
536  char *edges_sql,
537  pgr_edge_t **edges,
538  size_t *total_edges) {
539  bool ignore_id = false;
540  get_edges_5_columns(edges_sql, edges, total_edges, ignore_id);
541 }
542 
543 void
545  char *edges_sql,
546  pgr_edge_t **edges,
547  size_t *total_edges) {
548  bool ignore_id = true;
549  get_edges_5_columns(edges_sql, edges, total_edges, ignore_id);
550 }
551 
552 void
554  char *edges_sql,
556  size_t *total_edges) {
557  get_edges_9_columns(edges_sql, edges, total_edges, true);
558 }
559 void
561  char *edges_sql,
563  size_t *total_edges) {
564  get_edges_9_columns(edges_sql, edges, total_edges, false);
565 }
566 
567 void
569  char *sql,
571  size_t *total_edges) {
572  bool ignore_id = false;
573  get_edges_basic(sql, edges, total_edges, ignore_id);
574 }
int64_t pgr_SPI_getBigInt(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info)
int64_t target
Definition: pgr_types.h:63
double reverse_cost
Definition: pgr_types.h:132
double x1
Definition: pgr_types.h:66
void pgr_get_basic_edges(char *sql, pgr_basic_edge_t **edges, size_t *total_edges)
read basic edges
Definition: edges_input.c:568
int64_t source
Definition: pgr_types.h:129
int64_t target
Definition: pgr_types.h:130
#define PGR_DBG(...)
Definition: debug_macro.h:33
double cost
Definition: pgr_types.h:64
void pgr_get_edges(char *edges_sql, pgr_edge_t **edges, size_t *total_edges)
basic edge_sql
Definition: edges_input.c:535
uint64_t type
Definition: pgr_types.h:186
int64_t source
Definition: pgr_types.h:62
void time_msg(char *msg, clock_t start_t, clock_t end_t)
Definition: time_msg.c:31
static void fetch_basic_edge(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info[5], int64_t *default_id, pgr_basic_edge_t *edge, size_t *valid_edges)
Definition: edges_input.c:34
char * name
Definition: pgr_types.h:188
static void fetch_edge(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info[5], int64_t *default_id, float8 default_rcost, pgr_edge_t *edge, size_t *valid_edges)
Definition: edges_input.c:57
double y2
Definition: pgr_types.h:69
void pgr_fetch_column_info(Column_info_t info[], int info_size)
double float8
Definition: dijkstra.h:47
void pgr_get_edges_no_id(char *edges_sql, pgr_edge_t **edges, size_t *total_edges)
edges_sql without id parameter
Definition: edges_input.c:544
void pgr_get_edges_xy(char *edges_sql, Pgr_edge_xy_t **edges, size_t *total_edges)
Edges with x, y vertices values.
Definition: edges_input.c:553
double x2
Definition: pgr_types.h:68
int64_t id
Definition: pgr_types.h:128
double cost
Definition: pgr_types.h:131
double y1
Definition: pgr_types.h:67
void pgr_get_flow_edges(char *sql, pgr_edge_t **edges, size_t *total_edges)
read edges for flow
Definition: edges_input.c:526
int64_t source
Definition: pgr_types.h:120
double reverse_cost
Definition: pgr_types.h:65
edge_astar_t * edges
Definition: BDATester.cpp:46
int64_t id
Definition: pgr_types.h:61
static void get_edges_5_columns(char *sql, pgr_edge_t **edges, size_t *totalTuples, bool ignore_id)
Definition: edges_input.c:238
static void fetch_edge_with_xy(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info[9], int64_t *default_id, float8 default_rcost, Pgr_edge_xy_t *edge, size_t *valid_edges, bool normal)
Definition: edges_input.c:87
int64_t target
Definition: pgr_types.h:121
void pgr_get_edges_xy_reversed(char *edges_sql, Pgr_edge_xy_t **edges, size_t *total_edges)
for many to 1 on aStar
Definition: edges_input.c:560
static void get_edges_flow(char *sql, pgr_edge_t **edges, size_t *totalTuples, bool ignore_id)
Definition: edges_input.c:337
bool column_found(int colNumber)
Portal pgr_SPI_cursor_open(SPIPlanPtr SPIplan)
static void get_edges_basic(char *sql, pgr_basic_edge_t **edges, size_t *totalTuples, bool ignore_id)
Definition: edges_input.c:430
double pgr_SPI_getFloat8(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info)
static void get_edges_9_columns(char *sql, Pgr_edge_xy_t **edges, size_t *total_edges, bool normal)
Definition: edges_input.c:129
SPIPlanPtr pgr_SPI_prepare(char *sql)
expectType eType
Definition: pgr_types.h:189