pgRouting  2.2
pgRouting extends the PostGIS / PostgreSQL geospatial database to provide geospatial routing functionality.
 All Classes Functions Variables Pages
many_to_dist_withPointsDD.c
1 /*PGR-GNU*****************************************************************
2 File: many_to_dist_driving_distance.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 // #define DEBUG
26 #include "postgres.h"
27 #include "executor/spi.h"
28 #include "funcapi.h"
29 #include "utils/array.h"
30 #include "catalog/pg_type.h"
31 #if PGSQL_VERSION > 92
32 #include "access/htup_details.h"
33 #endif
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"
41 #include "./../../common/src/arrays_input.h"
42 #include "./../../common/src/points_input.h"
43 #include "./../../withPoints/src/get_new_queries.h"
44 #include "./withPoints_dd_driver.h"
45 
46 
47 PG_FUNCTION_INFO_V1(many_withPointsDD);
48 #ifndef _MSC_VER
49 Datum
50 #else
51 PGDLLEXPORT Datum
52 #endif
53 many_withPointsDD(PG_FUNCTION_ARGS);
54 
55 static
56 void process(
57  char* edges_sql,
58  char* points_sql,
59  int64_t *start_pids_arr, size_t size_arr,
60  double distance,
61 
62  bool directed,
63  char *driving_side,
64  bool details,
65  bool equicost,
66 
67  General_path_element_t **result_tuples,
68  size_t *result_count ){
69 
70  driving_side[0] = tolower(driving_side[0]);
71  PGR_DBG("driving side:%c",driving_side[0]);
72  if (! ((driving_side[0] == 'r')
73  || (driving_side[0] == 'l'))) {
74  driving_side[0] = 'b';
75  }
76 
77 
78  pgr_SPI_connect();
79  Point_on_edge_t *points = NULL;
80  size_t total_points = 0;
81  pgr_get_points(points_sql, &points, &total_points);
82 
83  char *edges_of_points_query = NULL;
84  char *edges_no_points_query = NULL;
85  get_new_queries(
86  edges_sql, points_sql,
87  &edges_of_points_query,
88  &edges_no_points_query);
89 
90 
91  pgr_edge_t *edges_of_points = NULL;
92  size_t total_edges_of_points = 0;
93  pgr_get_data_5_columns(edges_of_points_query, &edges_of_points, &total_edges_of_points);
94 
95  pgr_edge_t *edges = NULL;
96  size_t total_edges = 0;
97  pgr_get_data_5_columns(edges_no_points_query, &edges, &total_edges);
98 
99  PGR_DBG("freeing allocated memory not used anymore");
100  free(edges_of_points_query);
101  free(edges_no_points_query);
102 
103  if ((total_edges + total_edges_of_points) == 0) {
104  PGR_DBG("No edges found");
105  (*result_count) = 0;
106  (*result_tuples) = NULL;
107  pgr_SPI_finish();
108  return;
109  }
110 
111  PGR_DBG("Starting processing");
112  char *err_msg = NULL;
113  clock_t start_t = clock();
114  int errcode = do_pgr_many_withPointsDD(
115  edges, total_edges,
116  points, total_points,
117  edges_of_points, total_edges_of_points,
118  start_pids_arr, size_arr,
119  distance,
120 
121  directed,
122  driving_side[0],
123  details,
124  equicost,
125 
126  result_tuples,
127  result_count,
128  &err_msg);
129  time_msg(" processing withPointsDD many starts", start_t, clock());
130 
131  PGR_DBG("Returning %ld tuples\n", *result_count);
132  PGR_DBG("Returned message = %s\n", err_msg);
133 
134  if (!err_msg) free(err_msg);
135 
136  pfree(edges);
137  pfree(edges_of_points);
138  pfree(points);
139 
140  pgr_SPI_finish();
141 
142  if (errcode) {
143  pgr_send_error(errcode);
144  }
145 }
146 
147 
148 
149 #ifndef _MSC_VER
150 Datum
151 #else
152 PGDLLEXPORT Datum
153 #endif
154 many_withPointsDD(PG_FUNCTION_ARGS) {
155  FuncCallContext *funcctx;
156  uint32_t call_cntr;
157  uint32_t max_calls;
158  TupleDesc tuple_desc;
159 
160  /*******************************************************************************/
161  /* MODIFY AS NEEDED */
162  /* */
163  General_path_element_t *result_tuples = 0;
164  size_t result_count = 0;
165  /* */
166  /*******************************************************************************/
167 
168 
169  if (SRF_IS_FIRSTCALL()) {
170  MemoryContext oldcontext;
171  funcctx = SRF_FIRSTCALL_INIT();
172  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
173 
174 
175  /*******************************************************************************/
176  /* MODIFY AS NEEDED */
177  // CREATE OR REPLACE FUNCTION pgr_withPointsDD(
178  // edges_sql TEXT,
179  // points_sql TEXT,
180  // start_pids anyarray,
181  // distance FLOAT,
182  //
183  // directed BOOLEAN -- DEFAULT true,
184  // driving_side CHAR -- DEFAULT 'b',
185  // details BOOLEAN -- DEFAULT false,
186  // equicost BOOLEAN -- DEFAULT false,
187 
188  int64_t *sourcesArr;
189  size_t num;
190 
191  sourcesArr = (int64_t*) pgr_get_bigIntArray(&num, PG_GETARG_ARRAYTYPE_P(2));
192  PGR_DBG("sourcesArr size %d ", num);
193 
194  PGR_DBG("Calling driving_many_to_dist_driver");
195  process(
196  pgr_text2char(PG_GETARG_TEXT_P(0)), // edges_sql
197  pgr_text2char(PG_GETARG_TEXT_P(1)), // points_sql
198  sourcesArr, num, // start_pids array
199  PG_GETARG_FLOAT8(3), // distance
200 
201  PG_GETARG_BOOL(4), // directed
202  pgr_text2char(PG_GETARG_TEXT_P(5)), // driving side
203  PG_GETARG_BOOL(6), // details
204  PG_GETARG_BOOL(7), // equicost
205  &result_tuples, &result_count);
206 
207  free(sourcesArr);
208 
209  /* total number of tuples to be returned */
210  funcctx->max_calls = (uint32_t)result_count;
211  funcctx->user_fctx = result_tuples;
212  if (get_call_result_type(fcinfo, NULL, &tuple_desc) != TYPEFUNC_COMPOSITE)
213  ereport(ERROR,
214  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
215  errmsg("function returning record called in context "
216  "that cannot accept type record")));
217 
218  funcctx->tuple_desc = tuple_desc;
219 
220  MemoryContextSwitchTo(oldcontext);
221  }
222 
223  /* stuff done on every call of the function */
224  funcctx = SRF_PERCALL_SETUP();
225 
226  call_cntr = funcctx->call_cntr;
227  max_calls = funcctx->max_calls;
228  tuple_desc = funcctx->tuple_desc;
229  result_tuples = (General_path_element_t*) funcctx->user_fctx;
230 
231  /* do when there is more left to send */
232  if (call_cntr < max_calls) {
233  HeapTuple tuple;
234  Datum result;
235  Datum *values;
236  char* nulls;
237 
238  values = palloc(6 * sizeof(Datum));
239  nulls = palloc(6 * sizeof(char));
240  // id, start_v, node, edge, cost, tot_cost
241  nulls[0] = ' ';
242  nulls[1] = ' ';
243  nulls[2] = ' ';
244  nulls[3] = ' ';
245  nulls[4] = ' ';
246  nulls[5] = ' ';
247  values[0] = Int32GetDatum(call_cntr + 1);
248  values[1] = Int64GetDatum(result_tuples[call_cntr].start_id);
249  values[2] = Int64GetDatum(result_tuples[call_cntr].node);
250  values[3] = Int64GetDatum(result_tuples[call_cntr].edge);
251  values[4] = Float8GetDatum(result_tuples[call_cntr].cost);
252  values[5] = Float8GetDatum(result_tuples[call_cntr].agg_cost);
253 
254  tuple = heap_formtuple(tuple_desc, values, nulls);
255 
256  /* make the tuple into a datum */
257  result = HeapTupleGetDatum(tuple);
258 
259  /* clean up (this is not really necessary) */
260  pfree(values);
261  pfree(nulls);
262 
263  SRF_RETURN_NEXT(funcctx, result);
264  } else {
265  /* do when there is no more left */
266  if (result_tuples) free(result_tuples);
267  SRF_RETURN_DONE(funcctx);
268  }
269 }
270