Compare commits

...

15 Commits

Author SHA1 Message Date
Markus Koch 561eec5afe Add a penalty when getting on and off a train
Fixes #7.
2024-04-08 18:46:13 +02:00
Markus Koch f1868aba04 Implement net_meta info for nodes
This fixes #6.
2021-06-20 14:48:38 +02:00
Markus Koch ff214722a8 Also check if the new path intersects for path_b 2021-06-20 14:46:07 +02:00
Markus Koch 7753ce8477 Only iterate from path_b to path_new when intersecting 2021-06-20 14:44:09 +02:00
Markus Koch 6ffee116c7 Print cost in search result 2021-03-13 13:07:33 +01:00
Markus Koch e01245cb98 Do not use z-coordinate for speed on TRAINLINE or ACCESS
Using the z-coordinate as is is a bad idea. When intersecting, a
new node will be generated. What z-coord should it be? This node
can now be part of two distinct types with different meanings for
it. So we need to implement weight as a path argument.

This commit hardcodes the speed for trains and access pathways as
a temporary workaround.
2021-03-13 13:02:19 +01:00
Markus Koch b12da0e421 Handle possible NULL-pointers for paths when rehashing the route 2021-03-13 12:08:43 +01:00
Markus Koch 50c39a52bb Never intersect trainlines 2021-03-13 11:27:50 +01:00
Markus Koch 9ce5765192 Set ACCESS speed to 99 until all problems with this are resolved 2021-03-04 22:02:31 +01:00
Markus Koch f37ec6d03f Also check access for dijkstra_net_meta_new_to_list 2021-03-04 22:01:13 +01:00
Markus Koch 12d5bdc738 Strdup access 2021-03-04 22:00:54 +01:00
Markus Koch faa5d7ca4b Introduce a penalty for entering / leaving the train
Done by upping the cost for walking on an access layer.
2021-02-26 19:33:21 +01:00
Markus Koch aa7256c12e Only allow to start on streets 2021-02-26 19:27:26 +01:00
Markus Koch a87ca8a949 Add example GeoJson for testing 2021-02-26 19:18:10 +01:00
Markus Koch 6ee084472a Implement trainline support 2021-02-26 19:15:48 +01:00
10 changed files with 498 additions and 57 deletions

View File

@ -0,0 +1,43 @@
[
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[
-856,
-305
],
[
-863,
-273
]
]
},
"properties": {
"name": "S1:Tom Lehrer Station South"
}
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[
-966,
27
],
[
-942,
44
]
]
},
"properties": {
"name": "S1:Mueller Station East"
}
},
{
}
]

View File

@ -0,0 +1,90 @@
[
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[
-1213,
-305
],
[
-771,
-305
],
[
-771,
-301
],
[
-645,
-101
]
]
},
"properties": {
"name": "Tom Lehrer Street"
}
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[
-852,
42
],
[
-937,
40
],
[
-1080,
42
],
[
-1087,
102
],
[
-1141,
121
]
]
},
"properties": {
"name": "Mister Mueller Street"
}
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[
-1028,
67
],
[
-1033,
-134
],
[
-1065,
-135
],
[
-1086,
-409
]
]
},
"properties": {
"name": "Heinzi Street"
}
},
{
}
]

View File

@ -0,0 +1,85 @@
[
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[
-967,
184
],
[
-960,
-51
],
[
-921,
-96
],
[
-878,
-111
],
[
-866,
-151
],
[
-867,
-213
],
[
-863,
-243
],
[
-863,
-309
],
[
-864,
-405
],
[
-864,
-551
],
[
-802,
-624
],
[
-688,
-662
],
[
-566,
-620
],
[
-522,
-534
],
[
-347,
-483
],
[
-126,
-467
],
[
36,
-472
]
]
},
"properties": {
"name": "S1",
"line": "S1"
}
},
{
}
]

View File

@ -12,6 +12,7 @@ int dijkstra_node_same (struct dijkstra_node *node_a,
int same = 1;
// Not the proper way to do it, but it works for now.
same &= (node_a->net_meta == node_b->net_meta);
same &= (fabs(node_a->position.x - node_b->position.x) < FP_THRESHOLD);
same &= (fabs(node_a->position.y - node_b->position.y) < FP_THRESHOLD);
same &= (node_a->position.z == node_b->position.z);
@ -28,7 +29,8 @@ int dijkstra_node_same (struct dijkstra_node *node_a,
struct dijkstra_node *dijkstra_node_new(float x,
float y,
int z,
int uid)
int uid,
struct dijkstra_net_meta *net_meta)
{
struct dijkstra_node *node;
@ -38,6 +40,7 @@ struct dijkstra_node *dijkstra_node_new(float x,
node->position.y = y;
node->position.z = z;
node->uid = uid;
node->net_meta = net_meta;
node->paths = NULL;
}
@ -71,7 +74,8 @@ struct dijkstra_node *dijkstra_node_exists(GList *list,
struct dijkstra_node *dijkstra_node_new_to_list(GList **list,
float x,
float y,
int z)
int z,
struct dijkstra_net_meta *net_meta)
{
struct dijkstra_node *node;
struct dijkstra_node *found;
@ -79,7 +83,7 @@ struct dijkstra_node *dijkstra_node_new_to_list(GList **list,
uid = g_list_length(*list);
node = dijkstra_node_new(x, y, z, uid);
node = dijkstra_node_new(x, y, z, uid, net_meta);
if (!node)
return NULL;
@ -168,11 +172,23 @@ float dijkstra_position_get_distance(struct position *position_a,
}
dijkstra_cost dijkstra_get_weight_from_distance(struct dijkstra_node *node_a,
struct dijkstra_node *node_b)
struct dijkstra_node *node_b,
enum dijkstra_net_type net_type)
{
float dist;
float scale;
switch (net_type) {
case TRAINLINE:
scale = 10.0;
break;
default:
scale = 1.0;
break;
}
dist = dijkstra_position_get_distance(&node_a->position, &node_b->position);
dist /= scale;
if (dist < DIJKSTRA_COST_MIN)
dist = DIJKSTRA_COST_MIN;
@ -188,7 +204,8 @@ dijkstra_cost dijkstra_get_weight_from_distance(struct dijkstra_node *node_a,
struct dijkstra_path *dijkstra_path_new(char *name,
struct dijkstra_node *source,
struct dijkstra_node *destination,
dijkstra_cost weight)
dijkstra_cost weight,
struct dijkstra_net_meta *net_meta)
{
struct dijkstra_path *path;
@ -197,13 +214,16 @@ struct dijkstra_path *dijkstra_path_new(char *name,
path->name = name;
if (weight == DIJKSTRA_WEIGHT_AUTO)
path->weight = dijkstra_get_weight_from_distance(source,
destination);
destination,
net_meta->type);
else
path->weight = weight;
path->source = NULL;
path->destination = NULL;
path->net_meta = net_meta;
if (dijkstra_connect_nodes_to_path(source, destination, path) != 0) {
report(LL_CRITICAL, "Connect nodes failed: %p with %p as %p (%s)",
source, destination, path, path->name);
@ -265,6 +285,8 @@ int dijkstra_path_intersect(struct dijkstra_solver *solver,
struct dijkstra_path *path_new;
struct dijkstra_node *node_new;
struct dijkstra_node *disconnected_node;
struct dijkstra_path *access_path = NULL;
struct dijkstra_path *target_path = NULL;
float p0_x, p0_y, p1_x, p1_y;
float p2_x, p2_y, p3_x, p3_y;
@ -278,13 +300,38 @@ int dijkstra_path_intersect(struct dijkstra_solver *solver,
if (!path_a || !path_b)
return -1;
if (path_a->net_meta->type == ACCESS) {
access_path = path_a;
target_path = path_b;
} else if (path_b->net_meta->type == ACCESS) {
access_path = path_b;
target_path = path_a;
}
if (access_path) {
if (target_path->net_meta->type != STREET &&
!strstr(access_path->net_meta->access, target_path->name)) {
return 0; // Don't intersect if access != name of target
}
} else {
if (path_a->net_meta->type != path_b->net_meta->type)
return 0; // Never intersect two layers of different types, unless it's through access layers
// path_a and path_b types are now always guaranteed to be the same
if (path_a->net_meta->type == TRAINLINE)
return 0; // Never intersect trainlines (apart from with access types)
}
if (!target_path)
target_path = path_b; // Needed for net_meta selection below
// Check height
p0_z = path_a->source->position.z;
p1_z = path_a->destination->position.z;
p2_z = path_b->source->position.z;
p3_z = path_b->destination->position.z;
if (!(p0_z == p1_z && p1_z == p2_z && p2_z == p3_z)) // We don't want to intersect on height, they must match exactly for all four points.
if (!access_path && // For access paths, z is invalid, so only check this if we are intersecting streets (trainlines are filtered out above)
!(p0_z == p1_z && p1_z == p2_z && p2_z == p3_z)) // We don't want to intersect on height, they must match exactly for all four points.
return 0; // No collision
p0_x = path_a->source->position.x;
@ -313,20 +360,25 @@ int dijkstra_path_intersect(struct dijkstra_solver *solver,
i_y = p0_y + (t * s1_y);
i_z = p0_z; // They must all on the same height when intersecting, so we can pick whichever.
node_new = dijkstra_node_new_to_list(&solver->nodes, i_x, i_y, i_z);
node_new = dijkstra_node_new_to_list(&solver->nodes, i_x, i_y, i_z, target_path->source->net_meta);
if (node_new != path_a->source && node_new != path_a->destination) {
path_new = dijkstra_path_dup_shallow(path_a);
solver->paths = g_list_append(solver->paths, (gpointer) path_new);
disconnected_node = dijkstra_disconnect_node_from_path(path_a, path_a->destination);
dijkstra_connect_destination_node_to_path(node_new, path_a);
path_a->weight = dijkstra_get_weight_from_distance(path_a->source, path_a->destination);
path_a->weight = dijkstra_get_weight_from_distance(
path_a->source,
path_a->destination,
path_new->net_meta->type);
dijkstra_connect_nodes_to_path(node_new, disconnected_node, path_new);
path_new->weight = dijkstra_get_weight_from_distance(path_new->source, path_new->destination);
path_new->weight = dijkstra_get_weight_from_distance(
path_new->source,
path_new->destination,
path_new->net_meta->type);
// TODO: I don't have to iterate over the *entire* array here, it should be enough to only iterate over the entries after path_b.
dijkstra_path_intersect_all(solver, path_new, path_new); // Since straight paths can only cross once, we don't need to check any newly created entries.
dijkstra_path_intersect_all(solver, path_b, path_new); // Since straight paths can only cross once, we don't need to check any newly created entries.
}
// Now do the same thing for path b
@ -336,10 +388,17 @@ int dijkstra_path_intersect(struct dijkstra_solver *solver,
disconnected_node = dijkstra_disconnect_node_from_path(path_b, path_b->destination);
dijkstra_connect_destination_node_to_path(node_new, path_b);
path_b->weight = dijkstra_get_weight_from_distance(path_b->source, path_b->destination);
path_b->weight = dijkstra_get_weight_from_distance(
path_b->source,
path_b->destination,
path_new->net_meta->type);
dijkstra_connect_nodes_to_path(node_new, disconnected_node, path_new);
path_new->weight = dijkstra_get_weight_from_distance(path_new->source, path_new->destination);
path_new->weight = dijkstra_get_weight_from_distance(path_new->source,
path_new->destination,
path_new->net_meta->type);
dijkstra_path_intersect_all(solver, path_a, path_new);
}
// In case neither if matches that means we are on the corner where two paths intersect at their ends.
@ -374,6 +433,7 @@ struct dijkstra_path *dijkstra_path_new_to_list(struct dijkstra_solver *solver,
int z1,
int z2,
char *name,
struct dijkstra_net_meta *net_meta,
dijkstra_cost weight)
{
struct dijkstra_node *n1, *n2;
@ -381,9 +441,9 @@ struct dijkstra_path *dijkstra_path_new_to_list(struct dijkstra_solver *solver,
GList *l_last;
struct dijkstra_path *path_last = NULL;
n1 = dijkstra_node_new_to_list(&solver->nodes, x1, y1, z1);
n2 = dijkstra_node_new_to_list(&solver->nodes, x2, y2, z2);
path = dijkstra_path_new(name, n1, n2, weight);
n1 = dijkstra_node_new_to_list(&solver->nodes, x1, y1, z1, net_meta);
n2 = dijkstra_node_new_to_list(&solver->nodes, x2, y2, z2, net_meta);
path = dijkstra_path_new(name, n1, n2, weight, net_meta);
l_last = g_list_last(solver->paths);
if (l_last)
@ -403,6 +463,7 @@ struct dijkstra_solver *dijkstra_solver_new()
if (solver) {
solver->nodes = NULL;
solver->paths = NULL;
solver->net_metas = NULL;
}
return solver;
@ -413,6 +474,7 @@ void dijkstra_solver_free(struct dijkstra_solver *solver)
GList *l;
struct dijkstra_path *path;
struct dijkstra_node *node;
struct dijkstra_net_meta *net_meta;
// Free memory
for (l = solver->paths; l != NULL; l = l->next) {
@ -430,6 +492,14 @@ void dijkstra_solver_free(struct dijkstra_solver *solver)
free(node);
}
g_list_free(solver->nodes);
for (l = solver->net_metas; l != NULL; l = l->next) {
net_meta = (struct dijkstra_net_meta*) l->data;
free(net_meta->name);
if (net_meta->access)
free(net_meta->access);
free(net_meta);
}
}
inline struct dijkstra_node *dijkstra_node_get_connection(struct dijkstra_node *node,
@ -453,13 +523,22 @@ inline struct dijkstra_node *dijkstra_node_get_connection(struct dijkstra_node *
struct dijkstra_node *dijkstra_node_find_closest_node(struct dijkstra_solver *solver,
struct position *position) {
GList *l = NULL;
GList *pl = NULL;
struct dijkstra_node *node = NULL;
struct dijkstra_node *closest_node = NULL;
struct dijkstra_path *path = NULL;
float closest_distance;
float distance;
for (l = solver->nodes; l != NULL; l = l->next) {
node = (struct dijkstra_node*) l->data;
for (pl = node->paths; pl != NULL; pl = pl->next) {
path = (struct dijkstra_path*) pl->data;
if (path->net_meta->type == STREET)
break;
}
if (!(path && path->net_meta->type == STREET))
continue; // Only start on nodes that are part of a street
distance = dijkstra_position_get_distance(position, &node->position);
if (!closest_node || distance < closest_distance) {
closest_node = node;
@ -469,3 +548,47 @@ struct dijkstra_node *dijkstra_node_find_closest_node(struct dijkstra_solver *so
return closest_node;
}
struct dijkstra_net_meta *dijkstra_net_meta_new(enum dijkstra_net_type net_type,
char *name,
char *access)
{
struct dijkstra_net_meta *net_meta;
net_meta = malloc(sizeof(*net_meta));
if (net_meta) {
net_meta->type = net_type;
net_meta->name = strdup(name);
if (access)
net_meta->access = strdup(access);
else
net_meta->access = NULL;
}
return net_meta;
}
struct dijkstra_net_meta *dijkstra_net_meta_new_to_list(struct dijkstra_solver *solver,
enum dijkstra_net_type net_type,
char *name,
char *access)
{
struct dijkstra_net_meta *net_meta;
GList *l = NULL;
if (net_type == STREET)
name = "all";
for (l = solver->net_metas; l != NULL; l = l->next) {
net_meta = l->data;
if (net_meta->type == net_type &&
!strcmp(net_meta->name, name) &&
(net_meta->access && (!strcmp(net_meta->access, access)))) {
return net_meta;
}
}
net_meta = dijkstra_net_meta_new(net_type, name, access);
solver->net_metas = g_list_append(solver->net_metas, (void *) net_meta);
return net_meta;
}

View File

@ -12,6 +12,7 @@ typedef int dijkstra_cost;
struct dijkstra_solver {
GList *nodes;
GList *paths;
GList *net_metas;
};
struct position {
@ -20,15 +21,25 @@ struct position {
int z;
};
enum dijkstra_net_type {STREET, TRAINLINE, ACCESS};
struct dijkstra_net_meta {
char *name;
enum dijkstra_net_type type;
char *access;
};
struct dijkstra_path {
struct dijkstra_node *source;
struct dijkstra_node *destination;
char *name;
dijkstra_cost weight;
struct dijkstra_net_meta *net_meta;
};
struct dijkstra_node {
struct position position;
struct dijkstra_net_meta *net_meta;
GList *paths;
@ -44,6 +55,7 @@ struct dijkstra_path *dijkstra_path_new_to_list(struct dijkstra_solver *solver,
int z1,
int z2,
char *name,
struct dijkstra_net_meta *net_meta,
dijkstra_cost weight);
struct dijkstra_solver *dijkstra_solver_new();
@ -57,11 +69,16 @@ struct dijkstra_node *dijkstra_node_find_closest_node(struct dijkstra_solver *so
void dijkstra_path_intersect_all(struct dijkstra_solver *solver,
struct dijkstra_path *path,
struct dijkstra_path *path_last);
struct dijkstra_net_meta *dijkstra_net_meta_new_to_list(struct dijkstra_solver *solver,
enum dijkstra_net_type net_type,
char *name,
char *access);
/* For debugging only */
struct dijkstra_node *dijkstra_node_new_to_list(GList **list,
float x,
float y,
int z);
int z,
struct dijkstra_net_meta *net_meta);
#endif // DIJKSTRAGRAPH_H

View File

@ -112,6 +112,11 @@ struct dijkstra_node *dijkstra_search_process_queue(struct dijkstra_search *sear
for (l = node->paths; l != NULL; l = l->next) {
path = (struct dijkstra_path*) l->data;
cost = state->cost + path->weight;
if (state->cheapest_path && path->net_meta->type == ACCESS) { // If we just jumped onto an access path
if (state->cheapest_path->net_meta->type != ACCESS) {// and we came from a non-access path (getting on or off)
cost += (DIJKSTRA_ACCESS_PENALTY * 100.0); // add a penalty
}
}
connection = dijkstra_node_get_connection(node, path);
@ -235,6 +240,9 @@ int dijkstra_search_route_to_geojson(struct dijkstra_search *search,
GList *l = NULL;
struct dijkstra_node *node = NULL;
struct dijkstra_node *node_last = NULL;
struct dijkstra_path *path_to_this = NULL;
struct dijkstra_path *path_to_next = NULL;
float heading = -1.0;
float last_heading = 0;
float heading_diff;
@ -249,6 +257,17 @@ int dijkstra_search_route_to_geojson(struct dijkstra_search *search,
for (l = route; l != NULL; l = l->next) {
node = (struct dijkstra_node*) l->data;
if (node_last) {
path_to_this = search->states[node_last->uid]->cheapest_path;
path_to_next = search->states[node->uid]->cheapest_path;
if (!path_to_next) {
report(LL_CRITICAL, "INTERNAL ERROR: path_to_next is NULL");
break;
}
if (!path_to_this) {
// This happens at the very beginning.
path_to_this = path_to_next; // Pretend we were already where we started.
}
heading = atan2f((node->position.y - node_last->position.y), (node->position.x - node_last->position.x)) / (M_PI * 2) * 360;
if (heading < 0.0)
heading += 360;
@ -262,12 +281,32 @@ int dijkstra_search_route_to_geojson(struct dijkstra_search *search,
} else {
relative_direction_str = "straight";
}
if (node_last == search->start)
format_str = "Start on %2$s";
else if (search->states[node_last->uid]->cheapest_path->name == search->states[node->uid]->cheapest_path->name)
format_str = "Stay on %2$s by going %1$s";
else
format_str = "Go %s onto %s";
format_str = "Internal error in format_str in dijkstra_search_route_to_geojson()";
switch (path_to_next->net_meta->type) {
case STREET:
if (node_last == search->start)
format_str = "Start on %2$s";
else if (path_to_this->name == path_to_next->name)
format_str = "Stay on %2$s by going %1$s";
else
format_str = "Go %s onto %s";
break;
case TRAINLINE:
if (path_to_this->net_meta->type == ACCESS) // Enter train
format_str = "[T] Get on the %2$s";
else // Stay on train
format_str = "[T] Stay on the %2$s";
break;
case ACCESS:
if (path_to_this->net_meta->type == TRAINLINE) // Enter station from train
format_str = "[T] Leave the train at %2$s to your %1$s";
else // Enter station from street
format_str = "[T] Enter %2$s on your %1$s";
break;
}
if (node_last != search->start)
sdprintf(buf, &offset, ",");
@ -276,13 +315,14 @@ int dijkstra_search_route_to_geojson(struct dijkstra_search *search,
" \"geometry\": {\n"
" \"type\": \"LineString\", \"coordinates\": [[%f,%f],[%f,%f]]\n"
" },\n",
node_last->position.x, node_last->position.y,
node->position.x, node->position.y);
node_last->position.x, node_last->position.y,
node->position.x, node->position.y);
sdprintf(buf, &offset, " \"properties\": {\n"
" \"heading\": \"%f\",\n"
" \"through\": \"%s\",\n",
heading, search->states[node->uid]->cheapest_path->name);
" \"through\": \"%s\",\n"
" \"cost\": \"%d\",\n"
" \"type\": \"%d\",\n",
heading, path_to_next->name, search->states[node->uid]->cost, path_to_next->net_meta->type);
sdprintf(buf, &offset, " \"description\": \"");
sdprintf(buf, &offset, format_str, relative_direction_str, search->states[node->uid]->cheapest_path->name);
sdprintf(buf, &offset, "\"\n");

View File

@ -5,6 +5,8 @@
#define DIJKSTRA_SEARCH_MAX_ITERATIONS 5000
#define DIJKSTRA_ACCESS_PENALTY 300.0
struct dijkstra_state {
struct dijkstra_path *cheapest_path;
dijkstra_cost cost;

View File

@ -7,7 +7,8 @@
#include <json-glib/json-glib.h>
int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
char *filename)
char *filename,
char *type)
{
JsonParser *parser;
JsonNode *root;
@ -20,15 +21,30 @@ int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
int i_max, j_max;
char *name = NULL;
char *access = NULL;
int x, y, z;
int x_last, y_last, z_last;
enum dijkstra_net_type net_type;
struct dijkstra_net_meta *net_meta;
struct _stats {
int nodes;
int paths;
} stats = {.nodes = 0, .paths = 0};
report(LL_INFO, "Loading GeoJson data from %s...", filename);
report(LL_INFO, "Loading GeoJson '%s' data from %s...", type, filename);
if (!strcmp("street", type))
net_type = STREET;
else if (!strcmp("trainline", type))
net_type = TRAINLINE;
else if (!strcmp("access", type))
net_type = ACCESS;
else {
report(LL_ERROR, "Type '%s' not supported.\n", type);
return EXIT_FAILURE;
}
parser = json_parser_new ();
@ -47,6 +63,7 @@ int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
arr = json_node_get_array(root);
if (arr) {
i_max = json_array_get_length(arr);
net_meta = NULL;
for (i = 0; i < i_max; i++)
{
node = json_array_get_element(arr, i);
@ -63,6 +80,31 @@ int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
json_reader_end_member(reader); // name
json_reader_end_member(reader); // properties
switch (net_type) {
case STREET:
if (!net_meta)
net_meta = dijkstra_net_meta_new_to_list(solver, net_type, NULL, NULL);
break;
case ACCESS:
access = name;
name = strchr(name, ':');
if (name == NULL) {
report(LL_ERROR,
"Invalid name for accesss. '%s'",
access);
g_object_unref(reader);
continue;
}
*name = '\0';
do
name++;
while (*name == ' ' && *name != '\0');
G_GNUC_FALLTHROUGH;
case TRAINLINE:
net_meta = dijkstra_net_meta_new_to_list(solver, net_type, name, access);
break;
}
json_reader_read_member(reader, "geometry");
json_reader_read_member(reader, "coordinates");
z_last = 0; // By default, let's assume height 0
@ -93,6 +135,7 @@ int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
x, y,
z, z_last,
name,
net_meta,
DIJKSTRA_WEIGHT_AUTO);
}

View File

@ -5,6 +5,7 @@
#include "dijkstragraph.h"
int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
char *filename);
char *filename,
char *type);
#endif // GEOJSON_H

View File

@ -12,31 +12,18 @@
struct dijkstra_node *start;
struct dijkstra_node *dest;
void add_test_map(struct dijkstra_solver *solver)
{
dijkstra_path_new_to_list(solver,
5,0,
5,10,
0,0,
"Vertical",
1);
dijkstra_path_new_to_list(solver,
0,5,
10,5,
0,0,
"Horizontal",
1);
}
void help(const char *exec)
{
fprintf(stderr,
"Usage: %s [OPTION] [FILE]...\n"
"Usage: %s [OPTION] [TYPE:FILE]...\n"
"Start the lifo-dijkstraserv routing server.\n\n"
"Available options:\n"
" -s\tset output to silent\n"
" -v\tincrease verbosity. Maybe used multiple times.\n"
" -p\tport number (default 6802)\n",
" -p\tport number (default 6802)\n\n"
"TYPE can be any of:\n"
" street (default), trainline, access\n\n"
"At least one GeoJson FILE must be presented.\n",
exec);
}
@ -50,6 +37,7 @@ int main(int argc, char *argv[])
GList *l = NULL;
struct dijkstra_node *node;
struct dijkstra_path *path;
char *file_name, *file_type;
int port = 6802;
struct dijkstra_serv *serv;
@ -68,7 +56,7 @@ int main(int argc, char *argv[])
set_log_level(0);
break;
case 'p':
port = atoi(argv[i]);
port = atoi(optarg);
break;
case ':':
case '?':
@ -93,7 +81,16 @@ int main(int argc, char *argv[])
/* Load map data -> Generate graph */
for (i = optind; i < argc; ++i) {
add_geojson_to_dijkstra(solver, argv[i]);
file_name = strchr(argv[i], ':');
if (!file_name) {
file_name = argv[i];
file_type = "street";
} else {
*file_name = '\0';
file_name++;
file_type = argv[i];
}
add_geojson_to_dijkstra(solver, file_name, file_type);
}
if (should_report(LL_NOISY)) {
@ -106,10 +103,10 @@ int main(int argc, char *argv[])
for (l = solver->paths; l != NULL; l = l->next) {
path = (struct dijkstra_path*) l->data;
fprintf(stderr, "Path %p: %5d (%f,%f) -> %5d (%f,%f) cost %d \t\"%s\"\n", path,
path->source->uid, path->source->position.x, path->source->position.y,
path->destination->uid, path->destination->position.x, path->destination->position.y,
path->weight,
path->name);
path->source->uid, path->source->position.x, path->source->position.y,
path->destination->uid, path->destination->position.x, path->destination->position.y,
path->weight,
path->name);
}
printf("\n");
}