18 #include <grass/gis.h>
19 #include <grass/Vect.h>
20 #include <grass/dbmi.h>
21 #include <grass/glocale.h>
22 #include <grass/dgl/graph.h>
23 #include <grass/neta.h>
39 int count, last, cur, result, index, more;
55 while (
db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
58 if (count == 0 || cur != last) {
66 *lengths = (
int *)G_calloc(count,
sizeof(
int));
67 *ids = (
int *)G_calloc(count,
sizeof(
int));
68 if (!*lengths || !*ids) {
77 while (
db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
80 if (count != 0 && cur != last)
82 if (count == 0 || cur != last)
91 static int cmp_int(
const void *a,
const void *
b)
93 return *(
int *)a - *(
int *)
b;
114 int walk_layer,
char *route_id,
char *times,
115 char *to_stop,
char *walk_length,
116 neta_timetable * timetable,
int **route_ids,
119 int more, i, stop, route, time, *stop_pnt, stop1, stop2;
123 dbColumn *column1, *column2, *column3;
128 struct field_info *Fi;
133 G_fatal_error(_(
"Unable to open database <%s> by driver <%s>"),
134 Fi->database, Fi->driver);
138 sprintf(buf,
"select %s from %s order by %s", route_id, Fi->table,
144 if (timetable->routes < 0)
147 sprintf(buf,
"select %s from %s order by %s", Fi->key, Fi->table,
152 if (timetable->stops < 0)
155 timetable->route_stops =
156 (
int **)G_calloc(timetable->routes,
sizeof(
int *));
157 timetable->route_times =
158 (
int **)G_calloc(timetable->routes,
sizeof(
int *));
159 timetable->stop_routes =
160 (
int **)G_calloc(timetable->stops,
sizeof(
int *));
161 timetable->stop_times = (
int **)G_calloc(timetable->stops,
sizeof(
int *));
162 timetable->walk_length = (
int *)G_calloc(timetable->stops,
sizeof(
int));
163 timetable->walk_stops = (
int **)G_calloc(timetable->stops,
sizeof(
int *));
164 timetable->walk_times = (
int **)G_calloc(timetable->stops,
sizeof(
int *));
165 if (!timetable->route_stops || !timetable->route_times ||
166 !timetable->stop_routes || !timetable->stop_times ||
167 !timetable->walk_length) {
172 for (i = 0; i < timetable->routes; i++) {
173 timetable->route_stops[i] =
174 (
int *)G_calloc(timetable->route_length[i],
sizeof(
int));
175 timetable->route_times[i] =
176 (
int *)G_calloc(timetable->route_length[i],
sizeof(
int));
177 if (!timetable->route_stops[i] || !timetable->route_times[i]) {
182 timetable->route_length[i] = 0;
185 for (i = 0; i < timetable->stops; i++) {
186 timetable->stop_routes[i] =
187 (
int *)G_calloc(timetable->stop_length[i],
sizeof(
int));
188 timetable->stop_times[i] =
189 (
int *)G_calloc(timetable->stop_length[i],
sizeof(
int));
190 if (!timetable->stop_routes[i] || !timetable->stop_times[i]) {
194 timetable->walk_length[i] = 0;
195 timetable->stop_length[i] = 0;
198 sprintf(buf,
"select %s, %s, %s from %s order by %s", Fi->key, route_id,
199 times, Fi->table, times);
212 while (
db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
220 (
int *)bsearch(&stop, *stop_ids, timetable->stops,
sizeof(
int),
221 cmp_int) - (*stop_ids);
223 (
int *)bsearch(&route, *route_ids, timetable->routes,
sizeof(
int),
224 cmp_int) - (*route_ids);
226 timetable->stop_routes[stop][timetable->stop_length[stop]] = route;
227 timetable->stop_times[stop][timetable->stop_length[stop]++] = time;
229 timetable->route_stops[route][timetable->route_length[route]] = stop;
230 timetable->route_times[route][timetable->route_length[route]++] =
235 if (walk_layer != -1) {
238 sprintf(buf,
"select %s, %s, %s from %s", Fi->key, to_stop,
239 walk_length, Fi->table);
244 G_warning(_(
"Unable to open select cursor: %s"),
252 while (
db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
256 (
int *)bsearch(&stop, *stop_ids, timetable->stops,
257 sizeof(
int), cmp_int);
262 (
int *)bsearch(&stop, *stop_ids, timetable->stops,
263 sizeof(
int), cmp_int);
265 stop = stop_pnt - (*stop_ids);
266 timetable->walk_length[stop]++;
272 for (i = 0; i < timetable->stops; i++) {
273 timetable->walk_stops[i] =
274 (
int *)G_calloc(timetable->walk_length[i],
sizeof(
int));
275 timetable->walk_times[i] =
276 (
int *)G_calloc(timetable->walk_length[i],
sizeof(
int));
277 if (!timetable->walk_stops[i] || !timetable->walk_times[i]) {
281 timetable->walk_length[i] = 0;
286 G_warning(_(
"Unable to open select cursor: %s"),
295 while (
db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
299 (
int *)bsearch(&stop, *stop_ids, timetable->stops,
300 sizeof(
int), cmp_int);
302 stop2 = stop_pnt - (*stop_ids);
306 (
int *)bsearch(&stop, *stop_ids, timetable->stops,
307 sizeof(
int), cmp_int);
309 stop1 = stop_pnt - (*stop_ids);
312 timetable->walk_stops[stop1][timetable->
313 walk_length[stop1]] = stop2;
314 timetable->walk_times[stop1][timetable->
315 walk_length[stop1]++] = time;
356 int v,
int route,
int rows,
int update,
357 neta_timetable_result * result,
dglHeap_s * heap)
359 if (result->dst[new_conns][to] == -1 ||
360 result->dst[new_conns][to] > new_dst) {
361 result->dst[new_conns][to] = new_dst;
362 result->prev_stop[new_conns][to] = v;
363 result->prev_route[new_conns][to] = route;
364 result->prev_conn[new_conns][to] = old_conns;
368 heap_data.
pv = (
void *)new_heap_data(new_conns, to);
393 int to_stop,
int start_time,
int min_change,
394 int max_changes,
int walking_change,
395 neta_timetable_result * result)
400 int opt_conns, rows = 1;
402 if (max_changes != -1)
403 rows = max_changes + 2;
406 result->dst = (
int **)G_calloc(rows,
sizeof(
int *));
407 result->prev_stop = (
int **)G_calloc(rows,
sizeof(
int *));
408 result->prev_route = (
int **)G_calloc(rows,
sizeof(
int *));
409 result->prev_conn = (
int **)G_calloc(rows,
sizeof(
int *));
411 if (!result->dst || !result->prev_stop || !result->prev_route ||
412 !result->prev_conn) {
417 for (i = 0; i < rows; i++) {
418 result->dst[i] = (
int *)G_calloc(timetable->stops,
sizeof(
int));
419 result->prev_stop[i] = (
int *)G_calloc(timetable->stops,
sizeof(
int));
420 result->prev_route[i] =
421 (
int *)G_calloc(timetable->stops,
sizeof(
int));
422 result->prev_conn[i] = (
int *)G_calloc(timetable->stops,
sizeof(
int));
423 if (!result->dst[i] || !result->prev_stop[i] || !result->prev_route[i]
424 || !result->prev_conn[i]) {
430 if (from_stop == to_stop) {
431 result->dst[0][to_stop] = start_time;
432 result->prev_route[0][to_stop] = result->prev_stop[0][to_stop] = -1;
438 if (walking_change > 1)
440 if (walking_change < 0 || max_changes == -1)
444 for (i = 0; i < rows; i++)
445 for (j = 0; j < timetable->stops; j++)
446 result->dst[i][j] = result->prev_stop[i][j] =
447 result->prev_route[i][j] = -1;
449 result->dst[0][from_stop] = start_time - min_change;
450 result->prev_stop[0][from_stop] = result->prev_route[0][from_stop] = -1;
453 heap_data.
pv = (
void *)new_heap_data(0, from_stop);
459 int new_conns, walk_conns,
update;
465 dist = heap_node.
key;
467 if (dist > result->dst[conns][v])
471 new_conns = (max_changes == -1) ? 0 : (conns + 1);
472 walk_conns = conns + walking_change;
475 if (walk_conns < rows) {
478 for (i = 0; i < timetable->walk_length[v]; i++) {
479 int to = timetable->walk_stops[v][i];
480 int new_dst = dist + timetable->walk_times[v][i];
483 rows, update, result, &heap);
487 if (new_conns >= rows)
490 for (i = 0; i < timetable->stop_length[v]; i++)
491 if (timetable->stop_times[v][i] >= dist + min_change) {
492 int route = timetable->stop_routes[v][i];
495 for (j = 0; j < timetable->route_length[route]; j++)
496 if (timetable->route_stops[route][j] == v)
499 for (; j < timetable->route_length[route]; j++) {
500 int to = timetable->route_stops[route][j];
503 timetable->route_times[route][j], v,
504 route, rows, 1, result, &heap);
510 for (i = 0; i < rows; i++)
511 if (result->dst[i][to_stop] != -1 &&
513 result->dst[opt_conns][to_stop] > result->dst[i][to_stop]))
515 result->routes = opt_conns;
518 return result->dst[opt_conns][to_stop];
539 for (i = 0; i < timetable->route_length[route]; i++)
540 if (timetable->route_stops[route][i] == stop)
541 return timetable->route_times[route][i];
554 for (i = 0; i < result->rows; i++) {
556 G_free(result->prev_stop[i]);
557 G_free(result->prev_route[i]);
560 G_free(result->prev_stop);
561 G_free(result->prev_route);
dbDriver * db_start_driver_open_database(const char *drvname, const char *dbname)
Open driver/database connection.
dbColumn * db_get_table_column(dbTable *table, int n)
returns column structure for given table and column number
sprintf(buf2,"%s", G3D_CATS_ELEMENT)
int db_close_cursor(dbCursor *cursor)
Close cursor.
void G_free(void *buf)
Free allocated memory.
struct field_info * Vect_get_field(struct Map_info *Map, int field)
Get information about link to database.
int db_close_database_shutdown_driver(dbDriver *driver)
Close driver/database connection.
void dglHeapFree(dglHeap_s *pheap, dglHeapCancelItem_fn pfnCancelItem)
void dglHeapInit(dglHeap_s *pheap)
int db_fetch(dbCursor *cursor, int position, int *more)
Fetch data.
dbTable * db_get_cursor_table(dbCursor *cursor)
dbValue * db_get_column_value(dbColumn *column)
returns column value for given column structure
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
char * db_get_string(dbString *x)
int db_set_string(dbString *x, const char *s)
int db_get_value_int(dbValue *value)
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
int dglHeapInsertMin(dglHeap_s *pheap, long key, unsigned char flags, dglHeapData_u value)
int dglHeapExtractMin(dglHeap_s *pheap, dglHeapNode_s *pnoderet)
int db_open_select_cursor(dbDriver *driver, dbString *select, dbCursor *cursor, int mode)
Open select cursor.
void db_init_string(dbString *x)