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
drivedist.c
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: drivedist.c
3 
4 Copyright (c) 2015 Celia Virginia Vergara Castillo
5 Mail: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 #include "postgres.h"
26 #include "executor/spi.h"
27 #include "funcapi.h"
28 #include "catalog/pg_type.h"
29 #if PGSQL_VERSION > 92
30 #include "access/htup_details.h"
31 #endif
32 
33 //#define DEBUG
34 
35 #include "fmgr.h"
36 #include "./../../common/src/debug_macro.h"
37 #include "./../../common/src/time_msg.h"
38 #include "./../../common/src/pgr_types.h"
39 #include "./../../common/src/postgres_connection.h"
40 #include "./../../common/src/edges_input.h"
42 
43 PGDLLEXPORT Datum driving_distance(PG_FUNCTION_ARGS);
44 
45 static
47  char* sql,
48  int64_t start_vertex,
49  float8 distance,
50  bool directed,
53 
54  pgr_edge_t *edges = NULL;
55  size_t total_edges = 0;
56 
57 
58  char *err_msg = (char *)"";
59 
60  PGR_DBG("Load data");
61 
62  pgr_get_edges(sql, &edges, &total_edges);
63 
64  if (total_edges == 0) {
65  PGR_DBG("No edges found");
66  *path = NULL;
67  (*path_count) = 0;
69  return;
70  }
71  PGR_DBG("total edges read %ld\n", total_edges);
72 
73  clock_t start_t = clock();
74  do_pgr_driving_distance(edges, total_edges,
75  start_vertex, distance,
76  directed,
77  path, path_count, &err_msg);
78  time_msg(" processing Driving Distance one start", start_t, clock());
79 
80 
81  PGR_DBG("total tuples found %ld\n", *path_count);
82  PGR_DBG("Returned message = %s\n", err_msg);
83 
84  pfree(edges);
86 }
87 
88 
90 PGDLLEXPORT Datum
91 driving_distance(PG_FUNCTION_ARGS) {
92  FuncCallContext *funcctx;
93  uint32_t call_cntr;
94  uint32_t max_calls;
95  TupleDesc tuple_desc;
96  General_path_element_t *ret_path = 0;
97 
98  /* stuff done only on the first call of the function */
99  if (SRF_IS_FIRSTCALL()) {
100  MemoryContext oldcontext;
101  size_t path_count = 0;
102 
103  /* create a function context for cross-call persistence */
104  funcctx = SRF_FIRSTCALL_INIT();
105 
106  /* switch to memory context appropriate for multiple function calls */
107  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
108 
109  /*************************************************************************************************************
110  QUERY
111  CREATE OR REPLACE FUNCTION _pgr_drivingDistance(edges_sql text, start_vid bigint, distance float8, directed BOOLEAN,
112  OUT seq integer, OUT node bigint, OUT edge bigint, OUT cost float, OUT agg_cost float)
113  *************************************************************************************************************/
114  PGR_DBG("Sub query %s\n", pgr_text2char(PG_GETARG_TEXT_P(0)));
115 
116  compute_driving_distance(pgr_text2char(PG_GETARG_TEXT_P(0)), // edges_sql
117  PG_GETARG_INT64(1), // start_vid
118  PG_GETARG_FLOAT8(2), // distance
119  PG_GETARG_BOOL(3), // directed
120  &ret_path, &path_count);
121 
122  /* total number of tuples to be returned */
123  funcctx->max_calls = (uint32_t)path_count;
124  funcctx->user_fctx = ret_path;
125 
126  if (get_call_result_type(fcinfo, NULL, &tuple_desc) != TYPEFUNC_COMPOSITE)
127  ereport(ERROR,
128  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
129  errmsg("function returning record called in context "
130  "that cannot accept type record")));
131 
132  funcctx->tuple_desc = tuple_desc;
133 
134  MemoryContextSwitchTo(oldcontext);
135  }
136 
137  /* stuff done on every call of the function */
138  funcctx = SRF_PERCALL_SETUP();
139 
140  call_cntr = funcctx->call_cntr;
141  max_calls = funcctx->max_calls;
142  tuple_desc = funcctx->tuple_desc;
143  ret_path = (General_path_element_t*) funcctx->user_fctx;
144 
145  /* do when there is more left to send */
146  if (call_cntr < max_calls) {
147  HeapTuple tuple;
148  Datum result;
149  Datum *values;
150  bool* nulls;
151 
152  values = palloc(5 * sizeof(Datum));
153  nulls = palloc(5 * sizeof(bool));
154 
155  // TODO version 3.0 change to
156  // values[0] = Int64GetDatum(ret_path[call_cntr].seq + 1);
157  nulls[0] = false;
158  nulls[1] = false;
159  nulls[2] = false;
160  nulls[3] = false;
161  nulls[4] = false;
162  values[0] = Int32GetDatum(ret_path[call_cntr].seq + 1);
163  values[1] = Int64GetDatum(ret_path[call_cntr].node);
164  values[2] = Int64GetDatum(ret_path[call_cntr].edge);
165  values[3] = Float8GetDatum(ret_path[call_cntr].cost);
166  values[4] = Float8GetDatum(ret_path[call_cntr].agg_cost);
167 
168  tuple = heap_form_tuple(tuple_desc, values, nulls);
169 
170  /* make the tuple into a datum */
171  result = HeapTupleGetDatum(tuple);
172 
173  /* clean up (this is not really necessary) */
174  pfree(values);
175  pfree(nulls);
176 
177  SRF_RETURN_NEXT(funcctx, result);
178  } else {
179  /* do when there is no more left */
180  if (ret_path) free(ret_path);
181  SRF_RETURN_DONE(funcctx);
182  }
183 }
184 
PG_FUNCTION_INFO_V1(driving_distance)
int path_count
Definition: BDATester.cpp:51
#define PGR_DBG(...)
Definition: debug_macro.h:33
void pgr_get_edges(char *edges_sql, pgr_edge_t **edges, size_t *total_edges)
basic edge_sql
Definition: edges_input.c:535
void time_msg(char *msg, clock_t start_t, clock_t end_t)
Definition: time_msg.c:31
void do_pgr_driving_distance(pgr_edge_t *data_edges, size_t total_edges, int64_t start_vertex, double distance, bool directedFlag, General_path_element_t **ret_path, size_t *path_count, char **err_msg)
void pgr_SPI_finish(void)
double float8
Definition: dijkstra.h:47
edge_astar_t * edges
Definition: BDATester.cpp:46
void pgr_SPI_connect(void)
path_element_t * path
Definition: BDATester.cpp:49
char * err_msg
Definition: BDATester.cpp:50
static void compute_driving_distance(char *sql, int64_t start_vertex, float8 distance, bool directed, General_path_element_t **path, size_t *path_count)
Definition: drivedist.c:46
PGDLLEXPORT Datum driving_distance(PG_FUNCTION_ARGS)
Definition: drivedist.c:91
char * pgr_text2char(text *in)