Compare commits
4 Commits
6d252d7755
...
faa5d7ca4b
Author | SHA1 | Date | |
---|---|---|---|
faa5d7ca4b | |||
aa7256c12e | |||
a87ca8a949 | |||
6ee084472a |
43
sample-geojson/access.json
Normal file
43
sample-geojson/access.json
Normal 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"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
}
|
||||
]
|
90
sample-geojson/streets.json
Normal file
90
sample-geojson/streets.json
Normal 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"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
}
|
||||
]
|
85
sample-geojson/trainlines.json
Normal file
85
sample-geojson/trainlines.json
Normal 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"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
}
|
||||
]
|
@ -168,11 +168,26 @@ 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: // Trainlines and access types use the z-coordinate
|
||||
case ACCESS: // for cost scaling.
|
||||
scale = (float)node_a->position.z;
|
||||
scale += (float)node_b->position.z;
|
||||
scale /= 200;
|
||||
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 +203,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 +213,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 +284,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 +299,32 @@ 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
|
||||
}
|
||||
|
||||
// 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;
|
||||
@ -320,10 +360,16 @@ int dijkstra_path_intersect(struct dijkstra_solver *solver,
|
||||
|
||||
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.
|
||||
@ -336,10 +382,15 @@ 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);
|
||||
}
|
||||
|
||||
// In case neither if matches that means we are on the corner where two paths intersect at their ends.
|
||||
@ -374,6 +425,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;
|
||||
@ -383,7 +435,7 @@ struct dijkstra_path *dijkstra_path_new_to_list(struct dijkstra_solver *solver,
|
||||
|
||||
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);
|
||||
path = dijkstra_path_new(name, n1, n2, weight, net_meta);
|
||||
|
||||
l_last = g_list_last(solver->paths);
|
||||
if (l_last)
|
||||
@ -403,6 +455,7 @@ struct dijkstra_solver *dijkstra_solver_new()
|
||||
if (solver) {
|
||||
solver->nodes = NULL;
|
||||
solver->paths = NULL;
|
||||
solver->net_metas = NULL;
|
||||
}
|
||||
|
||||
return solver;
|
||||
@ -413,6 +466,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 +484,12 @@ 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);
|
||||
free(net_meta);
|
||||
}
|
||||
}
|
||||
|
||||
inline struct dijkstra_node *dijkstra_node_get_connection(struct dijkstra_node *node,
|
||||
@ -453,13 +513,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 +538,42 @@ 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);
|
||||
net_meta->access = access;
|
||||
}
|
||||
|
||||
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)) {
|
||||
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;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ typedef int dijkstra_cost;
|
||||
struct dijkstra_solver {
|
||||
GList *nodes;
|
||||
GList *paths;
|
||||
GList *net_metas;
|
||||
};
|
||||
|
||||
struct position {
|
||||
@ -20,11 +21,20 @@ 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 {
|
||||
@ -44,6 +54,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,6 +68,10 @@ 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,
|
||||
|
@ -235,6 +235,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 +252,9 @@ 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;
|
||||
|
||||
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 +268,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,12 +302,13 @@ 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"
|
||||
" \"type\": \"%d\",\n",
|
||||
heading, path_to_next->name, 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);
|
||||
|
@ -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 ();
|
||||
|
||||
@ -63,9 +79,38 @@ int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
|
||||
json_reader_end_member(reader); // name
|
||||
json_reader_end_member(reader); // properties
|
||||
|
||||
if (net_type == 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');
|
||||
}
|
||||
|
||||
json_reader_read_member(reader, "geometry");
|
||||
json_reader_read_member(reader, "coordinates");
|
||||
z_last = 0; // By default, let's assume height 0
|
||||
switch (net_type) {
|
||||
case STREET:
|
||||
z_last = 0; // By default, let's assume height 0
|
||||
break;
|
||||
case TRAINLINE:
|
||||
z_last = 1000; // By default, let's assume 10x normal speed
|
||||
break;
|
||||
case ACCESS:
|
||||
z_last = 10; // By default, let's introduce a penalty to get on the train (ACCESS walk 10x slower)
|
||||
break;
|
||||
default:
|
||||
z_last = -1;
|
||||
}
|
||||
net_meta = dijkstra_net_meta_new_to_list(solver, net_type, name, access);
|
||||
if (json_reader_is_array(reader)) {
|
||||
j_max = json_reader_count_elements(reader);
|
||||
for (j = 0; j < j_max; j++) {
|
||||
@ -93,6 +138,7 @@ int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
|
||||
x, y,
|
||||
z, z_last,
|
||||
name,
|
||||
net_meta,
|
||||
DIJKSTRA_WEIGHT_AUTO);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
47
src/main.c
47
src/main.c
@ -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");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user