pgRouting  2.2
pgRouting extends the PostGIS / PostgreSQL geospatial database to provide geospatial routing functionality.
 All Classes Functions Variables Pages
distances_input.c
1 /*PGR-GNU*****************************************************************
2 File: distances_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 "./../../common/src/pgr_types.h"
28 #include "./../../common/src/postgres_connection.h"
29 #include "./../../common/src/get_check_data.h"
30 #include "./distances_input.h"
31 
32 
33 
34 static
35 void pgr_fetch_distance(
36  HeapTuple *tuple,
37  TupleDesc *tupdesc,
38  Column_info_t info[3],
39  Matrix_cell_t *distance) {
40 
41  distance->from_vid = pgr_SPI_getBigInt(tuple, tupdesc, info[0]);
42  distance->to_vid = pgr_SPI_getBigInt(tuple, tupdesc, info[1]);
43  distance->cost = pgr_SPI_getFloat8(tuple, tupdesc, info[2]);
44 }
45 
51 void pgr_get_distances(
52  char *sql,
53  Matrix_cell_t **distances,
54  size_t *total_distances) {
55 
56  const int tuple_limit = 1000000;
57 
58  size_t ntuples;
59  size_t total_tuples = 0;
60 
61  Column_info_t info[3];
62 
63  int i;
64  for (i = 0; i < 3; ++i) {
65  info[i].colNumber = -1;
66  info[i].type = 0;
67  info[i].strict = true;
68  info[i].eType = ANY_INTEGER;
69  }
70  info[0].name = strdup("start_vid");
71  info[1].name = strdup("end_vid");
72  info[2].name = strdup("agg_cost");
73 
74  info[2].eType = ANY_NUMERICAL;
75 
76 
77  void *SPIplan;
78  SPIplan = pgr_SPI_prepare(sql);
79 
80  Portal SPIportal;
81  SPIportal = pgr_SPI_cursor_open(SPIplan);
82 
83 
84  bool moredata = TRUE;
85  (*total_distances) = total_tuples;
86 
87  while (moredata == TRUE) {
88  SPI_cursor_fetch(SPIportal, TRUE, tuple_limit);
89  if (total_tuples == 0)
90  pgr_fetch_column_info(info, 5);
91 
92  ntuples = SPI_processed;
93  total_tuples += ntuples;
94 
95  if (ntuples > 0) {
96  if ((*distances) == NULL)
97  (*distances) = (Matrix_cell_t *)palloc0(total_tuples * sizeof(Matrix_cell_t));
98  else
99  (*distances) = (Matrix_cell_t *)repalloc((*distances), total_tuples * sizeof(Matrix_cell_t));
100 
101  if ((*distances) == NULL) {
102  elog(ERROR, "Out of memory");
103  }
104 
105  SPITupleTable *tuptable = SPI_tuptable;
106  TupleDesc tupdesc = SPI_tuptable->tupdesc;
107  PGR_DBG("processing %d edge tupĺes", ntuples);
108 
109  size_t t;
110  for (t = 0; t < ntuples; t++) {
111  HeapTuple tuple = tuptable->vals[t];
112  pgr_fetch_distance(&tuple, &tupdesc, info,
113  &(*distances)[total_tuples - ntuples + t]);
114  }
115  SPI_freetuptable(tuptable);
116  } else {
117  moredata = FALSE;
118  }
119  }
120 
121 
122  if (total_tuples == 0) {
123  (*total_distances) = 0;
124  PGR_DBG("NO distances");
125  return;
126  }
127 
128  (*total_distances) = total_tuples;
129  PGR_DBG("Finish reading %ld edges, %ld", total_tuples, (*total_distances));
130 }