Compare commits
3 Commits
master
...
feature/tr
Author | SHA1 | Date | |
---|---|---|---|
a01fbe4bea | |||
8f9d5c254a | |||
d24904c2d0 |
@ -1,43 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,90 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,85 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
]
|
|
@ -12,9 +12,9 @@ int dijkstra_node_same (struct dijkstra_node *node_a,
|
|||||||
int same = 1;
|
int same = 1;
|
||||||
|
|
||||||
// Not the proper way to do it, but it works for now.
|
// 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.x - node_b->position.x) < FP_THRESHOLD);
|
||||||
same &= (fabs(node_a->position.y - node_b->position.y) < FP_THRESHOLD);
|
same &= (fabs(node_a->position.y - node_b->position.y) < FP_THRESHOLD);
|
||||||
|
same &= (node_a->layer == node_b->layer);
|
||||||
same &= (node_a->position.z == node_b->position.z);
|
same &= (node_a->position.z == node_b->position.z);
|
||||||
|
|
||||||
return same;
|
return same;
|
||||||
@ -29,8 +29,8 @@ int dijkstra_node_same (struct dijkstra_node *node_a,
|
|||||||
struct dijkstra_node *dijkstra_node_new(float x,
|
struct dijkstra_node *dijkstra_node_new(float x,
|
||||||
float y,
|
float y,
|
||||||
int z,
|
int z,
|
||||||
int uid,
|
struct dijkstra_layer *layer,
|
||||||
struct dijkstra_net_meta *net_meta)
|
int uid)
|
||||||
{
|
{
|
||||||
struct dijkstra_node *node;
|
struct dijkstra_node *node;
|
||||||
|
|
||||||
@ -39,8 +39,8 @@ struct dijkstra_node *dijkstra_node_new(float x,
|
|||||||
node->position.x = x;
|
node->position.x = x;
|
||||||
node->position.y = y;
|
node->position.y = y;
|
||||||
node->position.z = z;
|
node->position.z = z;
|
||||||
|
node->layer = layer;
|
||||||
node->uid = uid;
|
node->uid = uid;
|
||||||
node->net_meta = net_meta;
|
|
||||||
node->paths = NULL;
|
node->paths = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ struct dijkstra_node *dijkstra_node_new_to_list(GList **list,
|
|||||||
float x,
|
float x,
|
||||||
float y,
|
float y,
|
||||||
int z,
|
int z,
|
||||||
struct dijkstra_net_meta *net_meta)
|
struct dijkstra_layer *layer)
|
||||||
{
|
{
|
||||||
struct dijkstra_node *node;
|
struct dijkstra_node *node;
|
||||||
struct dijkstra_node *found;
|
struct dijkstra_node *found;
|
||||||
@ -83,7 +83,7 @@ struct dijkstra_node *dijkstra_node_new_to_list(GList **list,
|
|||||||
|
|
||||||
uid = g_list_length(*list);
|
uid = g_list_length(*list);
|
||||||
|
|
||||||
node = dijkstra_node_new(x, y, z, uid, net_meta);
|
node = dijkstra_node_new(x, y, z, layer, uid);
|
||||||
if (!node)
|
if (!node)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -172,23 +172,24 @@ float dijkstra_position_get_distance(struct position *position_a,
|
|||||||
}
|
}
|
||||||
|
|
||||||
dijkstra_cost dijkstra_get_weight_from_distance(struct dijkstra_node *node_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 dist;
|
||||||
float scale;
|
float factor;
|
||||||
|
|
||||||
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 = dijkstra_position_get_distance(&node_a->position, &node_b->position);
|
||||||
dist /= scale;
|
|
||||||
|
factor = (node_a->layer->type == TRAINLINE ? ((float) node_a->position.z) / 100.0 : 1.0);
|
||||||
|
factor += (node_b->layer->type == TRAINLINE ? ((float) node_b->position.z) / 100.0 : 1.0);
|
||||||
|
factor /= 2;
|
||||||
|
|
||||||
|
/*if (node_a->layer->type != STREET || node_b->layer->type != STREET) {
|
||||||
|
report(LL_INFO, "%d-%d Factor is %f (from %d-%d)",
|
||||||
|
node_a->layer->type,node_b->layer->type, factor,
|
||||||
|
node_a->position.z, node_b->position.z);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
dist /= factor;
|
||||||
|
|
||||||
if (dist < DIJKSTRA_COST_MIN)
|
if (dist < DIJKSTRA_COST_MIN)
|
||||||
dist = DIJKSTRA_COST_MIN;
|
dist = DIJKSTRA_COST_MIN;
|
||||||
@ -204,8 +205,7 @@ dijkstra_cost dijkstra_get_weight_from_distance(struct dijkstra_node *node_a,
|
|||||||
struct dijkstra_path *dijkstra_path_new(char *name,
|
struct dijkstra_path *dijkstra_path_new(char *name,
|
||||||
struct dijkstra_node *source,
|
struct dijkstra_node *source,
|
||||||
struct dijkstra_node *destination,
|
struct dijkstra_node *destination,
|
||||||
dijkstra_cost weight,
|
dijkstra_cost weight)
|
||||||
struct dijkstra_net_meta *net_meta)
|
|
||||||
{
|
{
|
||||||
struct dijkstra_path *path;
|
struct dijkstra_path *path;
|
||||||
|
|
||||||
@ -214,16 +214,13 @@ struct dijkstra_path *dijkstra_path_new(char *name,
|
|||||||
path->name = name;
|
path->name = name;
|
||||||
if (weight == DIJKSTRA_WEIGHT_AUTO)
|
if (weight == DIJKSTRA_WEIGHT_AUTO)
|
||||||
path->weight = dijkstra_get_weight_from_distance(source,
|
path->weight = dijkstra_get_weight_from_distance(source,
|
||||||
destination,
|
destination);
|
||||||
net_meta->type);
|
|
||||||
else
|
else
|
||||||
path->weight = weight;
|
path->weight = weight;
|
||||||
|
|
||||||
path->source = NULL;
|
path->source = NULL;
|
||||||
path->destination = NULL;
|
path->destination = NULL;
|
||||||
|
|
||||||
path->net_meta = net_meta;
|
|
||||||
|
|
||||||
if (dijkstra_connect_nodes_to_path(source, destination, path) != 0) {
|
if (dijkstra_connect_nodes_to_path(source, destination, path) != 0) {
|
||||||
report(LL_CRITICAL, "Connect nodes failed: %p with %p as %p (%s)",
|
report(LL_CRITICAL, "Connect nodes failed: %p with %p as %p (%s)",
|
||||||
source, destination, path, path->name);
|
source, destination, path, path->name);
|
||||||
@ -285,14 +282,18 @@ int dijkstra_path_intersect(struct dijkstra_solver *solver,
|
|||||||
struct dijkstra_path *path_new;
|
struct dijkstra_path *path_new;
|
||||||
struct dijkstra_node *node_new;
|
struct dijkstra_node *node_new;
|
||||||
struct dijkstra_node *disconnected_node;
|
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 p0_x, p0_y, p1_x, p1_y;
|
||||||
float p2_x, p2_y, p3_x, p3_y;
|
float p2_x, p2_y, p3_x, p3_y;
|
||||||
int p0_z, p1_z, p2_z, p3_z;
|
int p0_z, p1_z, p2_z, p3_z;
|
||||||
|
struct dijkstra_layer *p0_layer, *p1_layer, *p2_layer, *p3_layer;
|
||||||
float i_x, i_y;
|
float i_x, i_y;
|
||||||
int i_z;
|
int i_z;
|
||||||
|
struct dijkstra_layer *i_layer;
|
||||||
|
|
||||||
|
struct dijkstra_layer *access_layer = NULL;
|
||||||
|
struct dijkstra_layer *target_layer = NULL;
|
||||||
|
int target_z = -10000000;
|
||||||
|
|
||||||
float s1_x, s1_y, s2_x, s2_y;
|
float s1_x, s1_y, s2_x, s2_y;
|
||||||
float s, t;
|
float s, t;
|
||||||
@ -300,29 +301,62 @@ int dijkstra_path_intersect(struct dijkstra_solver *solver,
|
|||||||
if (!path_a || !path_b)
|
if (!path_a || !path_b)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (path_a->net_meta->type == ACCESS) {
|
// Process layer
|
||||||
access_path = path_a;
|
p0_layer = path_a->source->layer;
|
||||||
target_path = path_b;
|
p1_layer = path_a->destination->layer;
|
||||||
} else if (path_b->net_meta->type == ACCESS) {
|
p2_layer = path_b->source->layer;
|
||||||
access_path = path_b;
|
p3_layer = path_b->destination->layer;
|
||||||
target_path = path_a;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (access_path) {
|
if (p0_layer->type == ACCESS) {
|
||||||
if (target_path->net_meta->type != STREET &&
|
access_layer = p0_layer;
|
||||||
!strstr(access_path->net_meta->access, target_path->name)) {
|
target_layer = p2_layer;
|
||||||
return 0; // Don't intersect if access != name of target
|
target_z = path_b->source->position.z;
|
||||||
}
|
} else if (p1_layer->type == ACCESS) {
|
||||||
|
access_layer = p1_layer;
|
||||||
|
target_layer = p2_layer;
|
||||||
|
target_z = path_b->source->position.z;
|
||||||
|
} else if (p2_layer->type == ACCESS) {
|
||||||
|
access_layer = p2_layer;
|
||||||
|
target_layer = p0_layer;
|
||||||
|
target_z = path_a->source->position.z;
|
||||||
|
} else if (p3_layer->type == ACCESS) {
|
||||||
|
access_layer = p3_layer;
|
||||||
|
target_layer = p0_layer;
|
||||||
|
target_z = path_a->source->position.z;
|
||||||
} else {
|
} else {
|
||||||
if (path_a->net_meta->type != path_b->net_meta->type)
|
target_layer = p0_layer;
|
||||||
return 0; // Never intersect two layers of different types, unless it's through access layers
|
target_z = path_a->source->position.z; // For normal intersections, all .z must be the same, so we can pick any.
|
||||||
// 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)
|
if (access_layer) {
|
||||||
target_path = path_b; // Needed for net_meta selection below
|
if (target_layer->type == ACCESS)
|
||||||
|
return 0;
|
||||||
|
if (target_layer->type == TRAINLINE && strcmp(access_layer->access, target_layer->name))
|
||||||
|
return 0;
|
||||||
|
// report(LL_DEBUG, "ACCESS OK");
|
||||||
|
} else {
|
||||||
|
if (p0_layer->type == TRAINLINE ||
|
||||||
|
p1_layer->type == TRAINLINE ||
|
||||||
|
p2_layer->type == TRAINLINE ||
|
||||||
|
p3_layer->type == TRAINLINE)
|
||||||
|
return 0; // Never collide trains (sounds like a good idea, doesn't it!)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (access_layer) {
|
||||||
|
target_layer = access_layer; // Without this, I will (sometimes??) get a direct link between the two layers
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (p0_layer->type == ACCESS || p1_layer->type == ACCESS) {
|
||||||
|
//if (p2_layer->type == TRAINLINE && strcmp(p0_layer->access, p2_layer->name))
|
||||||
|
// return 0;
|
||||||
|
} else if (p2_layer->type == ACCESS || p3_layer->type == ACCESS) {
|
||||||
|
//if (p0_layer->type == TRAINLINE && strcmp(p2_layer->access, p0_layer->name))
|
||||||
|
// return 0;
|
||||||
|
} else if (p0_layer->type == TRAINLINE || p2_layer->type == TRAINLINE) {
|
||||||
|
report(LL_ERROR, "Prevent %d to %d", p0_layer->type, p2_layer->type);
|
||||||
|
return 0; // Never collide trains (sounds like a good idea, doesn't it!)
|
||||||
|
}*/
|
||||||
|
|
||||||
// Check height
|
// Check height
|
||||||
p0_z = path_a->source->position.z;
|
p0_z = path_a->source->position.z;
|
||||||
@ -330,9 +364,10 @@ int dijkstra_path_intersect(struct dijkstra_solver *solver,
|
|||||||
p2_z = path_b->source->position.z;
|
p2_z = path_b->source->position.z;
|
||||||
p3_z = path_b->destination->position.z;
|
p3_z = path_b->destination->position.z;
|
||||||
|
|
||||||
if (!access_path && // For access paths, z is invalid, so only check this if we are intersecting streets (trainlines are filtered out above)
|
if (p0_layer->type == STREET && p2_layer->type == STREET) {
|
||||||
!(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 (!(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
|
return 0; // No collision
|
||||||
|
}
|
||||||
|
|
||||||
p0_x = path_a->source->position.x;
|
p0_x = path_a->source->position.x;
|
||||||
p0_y = path_a->source->position.y;
|
p0_y = path_a->source->position.y;
|
||||||
@ -358,27 +393,24 @@ int dijkstra_path_intersect(struct dijkstra_solver *solver,
|
|||||||
// Collision detected
|
// Collision detected
|
||||||
i_x = p0_x + (t * s1_x);
|
i_x = p0_x + (t * s1_x);
|
||||||
i_y = p0_y + (t * s1_y);
|
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.
|
i_layer = target_layer;
|
||||||
|
i_z = target_z;
|
||||||
|
report(LL_DEBUG, "Split layer to type %d", i_layer->type);
|
||||||
|
|
||||||
node_new = dijkstra_node_new_to_list(&solver->nodes, i_x, i_y, i_z, target_path->source->net_meta);
|
node_new = dijkstra_node_new_to_list(&solver->nodes, i_x, i_y, i_z, i_layer);
|
||||||
if (node_new != path_a->source && node_new != path_a->destination) {
|
if (node_new != path_a->source && node_new != path_a->destination) {
|
||||||
path_new = dijkstra_path_dup_shallow(path_a);
|
path_new = dijkstra_path_dup_shallow(path_a);
|
||||||
solver->paths = g_list_append(solver->paths, (gpointer) path_new);
|
solver->paths = g_list_append(solver->paths, (gpointer) path_new);
|
||||||
|
|
||||||
disconnected_node = dijkstra_disconnect_node_from_path(path_a, path_a->destination);
|
disconnected_node = dijkstra_disconnect_node_from_path(path_a, path_a->destination);
|
||||||
dijkstra_connect_destination_node_to_path(node_new, path_a);
|
dijkstra_connect_destination_node_to_path(node_new, path_a);
|
||||||
path_a->weight = dijkstra_get_weight_from_distance(
|
path_a->weight = dijkstra_get_weight_from_distance(path_a->source, path_a->destination);
|
||||||
path_a->source,
|
|
||||||
path_a->destination,
|
|
||||||
path_new->net_meta->type);
|
|
||||||
|
|
||||||
dijkstra_connect_nodes_to_path(node_new, disconnected_node, path_new);
|
dijkstra_connect_nodes_to_path(node_new, disconnected_node, path_new);
|
||||||
path_new->weight = dijkstra_get_weight_from_distance(
|
path_new->weight = dijkstra_get_weight_from_distance(path_new->source, path_new->destination);
|
||||||
path_new->source,
|
|
||||||
path_new->destination,
|
|
||||||
path_new->net_meta->type);
|
|
||||||
|
|
||||||
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.
|
// 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.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now do the same thing for path b
|
// Now do the same thing for path b
|
||||||
@ -388,17 +420,10 @@ int dijkstra_path_intersect(struct dijkstra_solver *solver,
|
|||||||
|
|
||||||
disconnected_node = dijkstra_disconnect_node_from_path(path_b, path_b->destination);
|
disconnected_node = dijkstra_disconnect_node_from_path(path_b, path_b->destination);
|
||||||
dijkstra_connect_destination_node_to_path(node_new, path_b);
|
dijkstra_connect_destination_node_to_path(node_new, path_b);
|
||||||
path_b->weight = dijkstra_get_weight_from_distance(
|
path_b->weight = dijkstra_get_weight_from_distance(path_b->source, path_b->destination);
|
||||||
path_b->source,
|
|
||||||
path_b->destination,
|
|
||||||
path_new->net_meta->type);
|
|
||||||
|
|
||||||
dijkstra_connect_nodes_to_path(node_new, disconnected_node, path_new);
|
dijkstra_connect_nodes_to_path(node_new, disconnected_node, path_new);
|
||||||
path_new->weight = dijkstra_get_weight_from_distance(path_new->source,
|
path_new->weight = dijkstra_get_weight_from_distance(path_new->source, path_new->destination);
|
||||||
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.
|
// In case neither if matches that means we are on the corner where two paths intersect at their ends.
|
||||||
@ -432,8 +457,8 @@ struct dijkstra_path *dijkstra_path_new_to_list(struct dijkstra_solver *solver,
|
|||||||
float y2,
|
float y2,
|
||||||
int z1,
|
int z1,
|
||||||
int z2,
|
int z2,
|
||||||
|
struct dijkstra_layer *layer,
|
||||||
char *name,
|
char *name,
|
||||||
struct dijkstra_net_meta *net_meta,
|
|
||||||
dijkstra_cost weight)
|
dijkstra_cost weight)
|
||||||
{
|
{
|
||||||
struct dijkstra_node *n1, *n2;
|
struct dijkstra_node *n1, *n2;
|
||||||
@ -441,9 +466,9 @@ struct dijkstra_path *dijkstra_path_new_to_list(struct dijkstra_solver *solver,
|
|||||||
GList *l_last;
|
GList *l_last;
|
||||||
struct dijkstra_path *path_last = NULL;
|
struct dijkstra_path *path_last = NULL;
|
||||||
|
|
||||||
n1 = dijkstra_node_new_to_list(&solver->nodes, x1, y1, z1, net_meta);
|
n1 = dijkstra_node_new_to_list(&solver->nodes, x1, y1, z1, layer);
|
||||||
n2 = dijkstra_node_new_to_list(&solver->nodes, x2, y2, z2, net_meta);
|
n2 = dijkstra_node_new_to_list(&solver->nodes, x2, y2, z2, layer);
|
||||||
path = dijkstra_path_new(name, n1, n2, weight, net_meta);
|
path = dijkstra_path_new(name, n1, n2, weight);
|
||||||
|
|
||||||
l_last = g_list_last(solver->paths);
|
l_last = g_list_last(solver->paths);
|
||||||
if (l_last)
|
if (l_last)
|
||||||
@ -463,7 +488,7 @@ struct dijkstra_solver *dijkstra_solver_new()
|
|||||||
if (solver) {
|
if (solver) {
|
||||||
solver->nodes = NULL;
|
solver->nodes = NULL;
|
||||||
solver->paths = NULL;
|
solver->paths = NULL;
|
||||||
solver->net_metas = NULL;
|
solver->layers = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return solver;
|
return solver;
|
||||||
@ -474,7 +499,6 @@ void dijkstra_solver_free(struct dijkstra_solver *solver)
|
|||||||
GList *l;
|
GList *l;
|
||||||
struct dijkstra_path *path;
|
struct dijkstra_path *path;
|
||||||
struct dijkstra_node *node;
|
struct dijkstra_node *node;
|
||||||
struct dijkstra_net_meta *net_meta;
|
|
||||||
|
|
||||||
// Free memory
|
// Free memory
|
||||||
for (l = solver->paths; l != NULL; l = l->next) {
|
for (l = solver->paths; l != NULL; l = l->next) {
|
||||||
@ -483,6 +507,8 @@ void dijkstra_solver_free(struct dijkstra_solver *solver)
|
|||||||
// Currently, we reuse the existing memory block when for the
|
// Currently, we reuse the existing memory block when for the
|
||||||
// name when cloning streets. As such, clearing it here will
|
// name when cloning streets. As such, clearing it here will
|
||||||
// cause a double free if the street has been split.
|
// cause a double free if the street has been split.
|
||||||
|
// NOTE: Currently, do NOT free path->access as it is part of
|
||||||
|
// path->name and will be freed along with it (or not lol).
|
||||||
free(path);
|
free(path);
|
||||||
}
|
}
|
||||||
g_list_free(solver->paths);
|
g_list_free(solver->paths);
|
||||||
@ -492,14 +518,6 @@ void dijkstra_solver_free(struct dijkstra_solver *solver)
|
|||||||
free(node);
|
free(node);
|
||||||
}
|
}
|
||||||
g_list_free(solver->nodes);
|
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,
|
inline struct dijkstra_node *dijkstra_node_get_connection(struct dijkstra_node *node,
|
||||||
@ -523,22 +541,15 @@ inline struct dijkstra_node *dijkstra_node_get_connection(struct dijkstra_node *
|
|||||||
struct dijkstra_node *dijkstra_node_find_closest_node(struct dijkstra_solver *solver,
|
struct dijkstra_node *dijkstra_node_find_closest_node(struct dijkstra_solver *solver,
|
||||||
struct position *position) {
|
struct position *position) {
|
||||||
GList *l = NULL;
|
GList *l = NULL;
|
||||||
GList *pl = NULL;
|
|
||||||
struct dijkstra_node *node = NULL;
|
struct dijkstra_node *node = NULL;
|
||||||
struct dijkstra_node *closest_node = NULL;
|
struct dijkstra_node *closest_node = NULL;
|
||||||
struct dijkstra_path *path = NULL;
|
|
||||||
float closest_distance;
|
float closest_distance;
|
||||||
float distance;
|
float distance;
|
||||||
|
|
||||||
for (l = solver->nodes; l != NULL; l = l->next) {
|
for (l = solver->nodes; l != NULL; l = l->next) {
|
||||||
node = (struct dijkstra_node*) l->data;
|
node = (struct dijkstra_node*) l->data;
|
||||||
for (pl = node->paths; pl != NULL; pl = pl->next) {
|
if (node->layer->type != STREET)
|
||||||
path = (struct dijkstra_path*) pl->data;
|
continue;
|
||||||
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);
|
distance = dijkstra_position_get_distance(position, &node->position);
|
||||||
if (!closest_node || distance < closest_distance) {
|
if (!closest_node || distance < closest_distance) {
|
||||||
closest_node = node;
|
closest_node = node;
|
||||||
@ -549,46 +560,41 @@ struct dijkstra_node *dijkstra_node_find_closest_node(struct dijkstra_solver *so
|
|||||||
return closest_node;
|
return closest_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dijkstra_net_meta *dijkstra_net_meta_new(enum dijkstra_net_type net_type,
|
struct dijkstra_layer *dijkstra_layer_new(enum dijkstra_layer_type type,
|
||||||
char *name,
|
char *name,
|
||||||
char *access)
|
char *access)
|
||||||
{
|
{
|
||||||
struct dijkstra_net_meta *net_meta;
|
struct dijkstra_layer *layer;
|
||||||
|
|
||||||
net_meta = malloc(sizeof(*net_meta));
|
layer = malloc(sizeof(*layer));
|
||||||
if (net_meta) {
|
if (layer) {
|
||||||
net_meta->type = net_type;
|
layer->name = strdup(name);
|
||||||
net_meta->name = strdup(name);
|
layer->type = type;
|
||||||
if (access)
|
layer->access = access;
|
||||||
net_meta->access = strdup(access);
|
|
||||||
else
|
|
||||||
net_meta->access = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return net_meta;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dijkstra_net_meta *dijkstra_net_meta_new_to_list(struct dijkstra_solver *solver,
|
struct dijkstra_layer *dijkstra_layer_new_to_list(struct dijkstra_solver *solver,
|
||||||
enum dijkstra_net_type net_type,
|
enum dijkstra_layer_type type,
|
||||||
char *name,
|
char *name,
|
||||||
char *access)
|
char *access)
|
||||||
{
|
{
|
||||||
struct dijkstra_net_meta *net_meta;
|
struct dijkstra_layer *layer;
|
||||||
GList *l = NULL;
|
GList *l = NULL;
|
||||||
|
|
||||||
if (net_type == STREET)
|
if (type == STREET)
|
||||||
name = "all";
|
name = "all";
|
||||||
|
|
||||||
for (l = solver->net_metas; l != NULL; l = l->next) {
|
for (l = solver->layers; l != NULL; l = l->next) {
|
||||||
net_meta = l->data;
|
layer = l->data;
|
||||||
if (net_meta->type == net_type &&
|
if (layer->type == type && !strcmp(layer->name, name)) {
|
||||||
!strcmp(net_meta->name, name) &&
|
return layer;
|
||||||
(net_meta->access && (!strcmp(net_meta->access, access)))) {
|
|
||||||
return net_meta;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
net_meta = dijkstra_net_meta_new(net_type, name, access);
|
layer = dijkstra_layer_new(type, name, access);
|
||||||
solver->net_metas = g_list_append(solver->net_metas, (void *) net_meta);
|
solver->layers = g_list_append(solver->layers, (void *) layer);
|
||||||
return net_meta;
|
return layer;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ typedef int dijkstra_cost;
|
|||||||
struct dijkstra_solver {
|
struct dijkstra_solver {
|
||||||
GList *nodes;
|
GList *nodes;
|
||||||
GList *paths;
|
GList *paths;
|
||||||
GList *net_metas;
|
GList *layers;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct position {
|
struct position {
|
||||||
@ -21,31 +21,35 @@ struct position {
|
|||||||
int z;
|
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_path {
|
||||||
struct dijkstra_node *source;
|
struct dijkstra_node *source;
|
||||||
struct dijkstra_node *destination;
|
struct dijkstra_node *destination;
|
||||||
char *name;
|
char *name;
|
||||||
dijkstra_cost weight;
|
dijkstra_cost weight;
|
||||||
struct dijkstra_net_meta *net_meta;
|
};
|
||||||
|
|
||||||
|
enum dijkstra_layer_type {STREET, TRAINLINE, ACCESS};
|
||||||
|
|
||||||
|
struct dijkstra_layer {
|
||||||
|
char *name;
|
||||||
|
enum dijkstra_layer_type type;
|
||||||
|
char *access;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dijkstra_node {
|
struct dijkstra_node {
|
||||||
struct position position;
|
struct position position;
|
||||||
struct dijkstra_net_meta *net_meta;
|
|
||||||
|
|
||||||
GList *paths;
|
GList *paths;
|
||||||
|
|
||||||
|
struct dijkstra_layer *layer; /* Layer (this will strcmp'd for matching) */
|
||||||
int uid;
|
int uid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct offset_map {
|
||||||
|
char *name;
|
||||||
|
int offset;
|
||||||
|
};
|
||||||
|
|
||||||
/* User Functions */
|
/* User Functions */
|
||||||
struct dijkstra_path *dijkstra_path_new_to_list(struct dijkstra_solver *solver,
|
struct dijkstra_path *dijkstra_path_new_to_list(struct dijkstra_solver *solver,
|
||||||
float x1,
|
float x1,
|
||||||
@ -54,13 +58,18 @@ struct dijkstra_path *dijkstra_path_new_to_list(struct dijkstra_solver *solver,
|
|||||||
float y2,
|
float y2,
|
||||||
int z1,
|
int z1,
|
||||||
int z2,
|
int z2,
|
||||||
|
struct dijkstra_layer *layer,
|
||||||
char *name,
|
char *name,
|
||||||
struct dijkstra_net_meta *net_meta,
|
|
||||||
dijkstra_cost weight);
|
dijkstra_cost weight);
|
||||||
|
|
||||||
struct dijkstra_solver *dijkstra_solver_new();
|
struct dijkstra_solver *dijkstra_solver_new();
|
||||||
void dijkstra_solver_free(struct dijkstra_solver *solver);
|
void dijkstra_solver_free(struct dijkstra_solver *solver);
|
||||||
|
|
||||||
|
struct dijkstra_layer *dijkstra_layer_new_to_list(struct dijkstra_solver *solver,
|
||||||
|
enum dijkstra_layer_type type,
|
||||||
|
char *name,
|
||||||
|
char *access);
|
||||||
|
|
||||||
/* Library functions */
|
/* Library functions */
|
||||||
struct dijkstra_node *dijkstra_node_get_connection(struct dijkstra_node *node,
|
struct dijkstra_node *dijkstra_node_get_connection(struct dijkstra_node *node,
|
||||||
struct dijkstra_path *path);
|
struct dijkstra_path *path);
|
||||||
@ -69,16 +78,12 @@ struct dijkstra_node *dijkstra_node_find_closest_node(struct dijkstra_solver *so
|
|||||||
void dijkstra_path_intersect_all(struct dijkstra_solver *solver,
|
void dijkstra_path_intersect_all(struct dijkstra_solver *solver,
|
||||||
struct dijkstra_path *path,
|
struct dijkstra_path *path,
|
||||||
struct dijkstra_path *path_last);
|
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 */
|
/* For debugging only */
|
||||||
struct dijkstra_node *dijkstra_node_new_to_list(GList **list,
|
struct dijkstra_node *dijkstra_node_new_to_list(GList **list,
|
||||||
float x,
|
float x,
|
||||||
float y,
|
float y,
|
||||||
int z,
|
int z,
|
||||||
struct dijkstra_net_meta *net_meta);
|
struct dijkstra_layer *layer);
|
||||||
|
|
||||||
#endif // DIJKSTRAGRAPH_H
|
#endif // DIJKSTRAGRAPH_H
|
||||||
|
@ -112,11 +112,6 @@ struct dijkstra_node *dijkstra_search_process_queue(struct dijkstra_search *sear
|
|||||||
for (l = node->paths; l != NULL; l = l->next) {
|
for (l = node->paths; l != NULL; l = l->next) {
|
||||||
path = (struct dijkstra_path*) l->data;
|
path = (struct dijkstra_path*) l->data;
|
||||||
cost = state->cost + path->weight;
|
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);
|
connection = dijkstra_node_get_connection(node, path);
|
||||||
|
|
||||||
@ -240,9 +235,7 @@ int dijkstra_search_route_to_geojson(struct dijkstra_search *search,
|
|||||||
GList *l = NULL;
|
GList *l = NULL;
|
||||||
struct dijkstra_node *node = NULL;
|
struct dijkstra_node *node = NULL;
|
||||||
struct dijkstra_node *node_last = NULL;
|
struct dijkstra_node *node_last = NULL;
|
||||||
struct dijkstra_path *path_to_this = NULL;
|
struct dijkstra_node *node_from = NULL;
|
||||||
struct dijkstra_path *path_to_next = NULL;
|
|
||||||
|
|
||||||
float heading = -1.0;
|
float heading = -1.0;
|
||||||
float last_heading = 0;
|
float last_heading = 0;
|
||||||
float heading_diff;
|
float heading_diff;
|
||||||
@ -257,17 +250,9 @@ int dijkstra_search_route_to_geojson(struct dijkstra_search *search,
|
|||||||
for (l = route; l != NULL; l = l->next) {
|
for (l = route; l != NULL; l = l->next) {
|
||||||
node = (struct dijkstra_node*) l->data;
|
node = (struct dijkstra_node*) l->data;
|
||||||
if (node_last) {
|
if (node_last) {
|
||||||
path_to_this = search->states[node_last->uid]->cheapest_path;
|
if (node_last->layer->type != ACCESS) {
|
||||||
path_to_next = search->states[node->uid]->cheapest_path;
|
node_from = node_last;
|
||||||
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;
|
heading = atan2f((node->position.y - node_last->position.y), (node->position.x - node_last->position.x)) / (M_PI * 2) * 360;
|
||||||
if (heading < 0.0)
|
if (heading < 0.0)
|
||||||
heading += 360;
|
heading += 360;
|
||||||
@ -281,31 +266,27 @@ int dijkstra_search_route_to_geojson(struct dijkstra_search *search,
|
|||||||
} else {
|
} else {
|
||||||
relative_direction_str = "straight";
|
relative_direction_str = "straight";
|
||||||
}
|
}
|
||||||
|
if (node_last == search->start) {
|
||||||
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";
|
format_str = "Start on %2$s";
|
||||||
else if (path_to_this->name == path_to_next->name)
|
} else if (node->layer->type == ACCESS && node_last->layer->type == ACCESS) {
|
||||||
|
|
||||||
|
if (node_from->layer->type == STREET)
|
||||||
|
format_str = "[T] Enter the %2$s entrance on your %1$s";
|
||||||
|
else
|
||||||
|
format_str = "[T] Get off the train at %2$s towards your %1$s";
|
||||||
|
|
||||||
|
} else if (search->states[node_last->uid]->cheapest_path->name == search->states[node->uid]->cheapest_path->name) {
|
||||||
|
if (node_last->layer->type == TRAINLINE)
|
||||||
|
format_str = "Waypoint for %2$s (going %1$s)"; // TODO: check whether we are passing a station
|
||||||
|
else
|
||||||
format_str = "Stay on %2$s by going %1$s";
|
format_str = "Stay on %2$s by going %1$s";
|
||||||
|
} else if ((node->layer->type == TRAINLINE || node->layer->type == ACCESS) && node_last->layer->type == ACCESS) {
|
||||||
|
format_str = "[T] Take the %2$s"; // TODO: Somewhere here we probably also have the interchange
|
||||||
|
} else {
|
||||||
|
if (node_last->layer->type == TRAINLINE)
|
||||||
|
format_str = "[T] Leave the train at %2$s";
|
||||||
else
|
else
|
||||||
format_str = "Go %s onto %s";
|
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)
|
if (node_last != search->start)
|
||||||
@ -319,10 +300,9 @@ int dijkstra_search_route_to_geojson(struct dijkstra_search *search,
|
|||||||
node->position.x, node->position.y);
|
node->position.x, node->position.y);
|
||||||
sdprintf(buf, &offset, " \"properties\": {\n"
|
sdprintf(buf, &offset, " \"properties\": {\n"
|
||||||
" \"heading\": \"%f\",\n"
|
" \"heading\": \"%f\",\n"
|
||||||
" \"through\": \"%s\",\n"
|
" \"through\": \"%s\",\n",
|
||||||
" \"cost\": \"%d\",\n"
|
heading, search->states[node->uid]->cheapest_path->name);
|
||||||
" \"type\": \"%d\",\n",
|
sdprintf(buf, &offset, " \"layertype\": \"%d->%d\",\n", node_last->layer->type, node->layer->type);
|
||||||
heading, path_to_next->name, search->states[node->uid]->cost, path_to_next->net_meta->type);
|
|
||||||
sdprintf(buf, &offset, " \"description\": \"");
|
sdprintf(buf, &offset, " \"description\": \"");
|
||||||
sdprintf(buf, &offset, format_str, relative_direction_str, search->states[node->uid]->cheapest_path->name);
|
sdprintf(buf, &offset, format_str, relative_direction_str, search->states[node->uid]->cheapest_path->name);
|
||||||
sdprintf(buf, &offset, "\"\n");
|
sdprintf(buf, &offset, "\"\n");
|
||||||
@ -331,7 +311,9 @@ int dijkstra_search_route_to_geojson(struct dijkstra_search *search,
|
|||||||
sdprintf(buf, &offset, "}");
|
sdprintf(buf, &offset, "}");
|
||||||
last_heading = heading;
|
last_heading = heading;
|
||||||
}
|
}
|
||||||
|
|
||||||
node_last = node;
|
node_last = node;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sdprintf(buf, &offset, "\n]\n");
|
sdprintf(buf, &offset, "\n]\n");
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
|
|
||||||
#define DIJKSTRA_SEARCH_MAX_ITERATIONS 5000
|
#define DIJKSTRA_SEARCH_MAX_ITERATIONS 5000
|
||||||
|
|
||||||
#define DIJKSTRA_ACCESS_PENALTY 300.0
|
|
||||||
|
|
||||||
struct dijkstra_state {
|
struct dijkstra_state {
|
||||||
struct dijkstra_path *cheapest_path;
|
struct dijkstra_path *cheapest_path;
|
||||||
dijkstra_cost cost;
|
dijkstra_cost cost;
|
||||||
|
@ -7,8 +7,7 @@
|
|||||||
#include <json-glib/json-glib.h>
|
#include <json-glib/json-glib.h>
|
||||||
|
|
||||||
int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
|
int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
|
||||||
char *filename,
|
char *filename, char *type)
|
||||||
char *type)
|
|
||||||
{
|
{
|
||||||
JsonParser *parser;
|
JsonParser *parser;
|
||||||
JsonNode *root;
|
JsonNode *root;
|
||||||
@ -24,9 +23,9 @@ int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
|
|||||||
char *access = NULL;
|
char *access = NULL;
|
||||||
int x, y, z;
|
int x, y, z;
|
||||||
int x_last, y_last, z_last;
|
int x_last, y_last, z_last;
|
||||||
|
char *layer_name;
|
||||||
enum dijkstra_net_type net_type;
|
enum dijkstra_layer_type layer_type;
|
||||||
struct dijkstra_net_meta *net_meta;
|
struct dijkstra_layer *layer = NULL;
|
||||||
|
|
||||||
struct _stats {
|
struct _stats {
|
||||||
int nodes;
|
int nodes;
|
||||||
@ -35,12 +34,12 @@ int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
|
|||||||
|
|
||||||
report(LL_INFO, "Loading GeoJson '%s' data from %s...", type, filename);
|
report(LL_INFO, "Loading GeoJson '%s' data from %s...", type, filename);
|
||||||
|
|
||||||
if (!strcmp("street", type))
|
if (!strcmp("streets", type))
|
||||||
net_type = STREET;
|
layer_type = STREET;
|
||||||
else if (!strcmp("trainline", type))
|
else if (!strcmp("trainlines", type))
|
||||||
net_type = TRAINLINE;
|
layer_type = TRAINLINE;
|
||||||
else if (!strcmp("access", type))
|
else if (!strcmp("access", type))
|
||||||
net_type = ACCESS;
|
layer_type = ACCESS;
|
||||||
else {
|
else {
|
||||||
report(LL_ERROR, "Type '%s' not supported.\n", type);
|
report(LL_ERROR, "Type '%s' not supported.\n", type);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
@ -63,7 +62,6 @@ int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
|
|||||||
arr = json_node_get_array(root);
|
arr = json_node_get_array(root);
|
||||||
if (arr) {
|
if (arr) {
|
||||||
i_max = json_array_get_length(arr);
|
i_max = json_array_get_length(arr);
|
||||||
net_meta = NULL;
|
|
||||||
for (i = 0; i < i_max; i++)
|
for (i = 0; i < i_max; i++)
|
||||||
{
|
{
|
||||||
node = json_array_get_element(arr, i);
|
node = json_array_get_element(arr, i);
|
||||||
@ -80,12 +78,7 @@ int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
|
|||||||
json_reader_end_member(reader); // name
|
json_reader_end_member(reader); // name
|
||||||
json_reader_end_member(reader); // properties
|
json_reader_end_member(reader); // properties
|
||||||
|
|
||||||
switch (net_type) {
|
if (layer_type == ACCESS) {
|
||||||
case STREET:
|
|
||||||
if (!net_meta)
|
|
||||||
net_meta = dijkstra_net_meta_new_to_list(solver, net_type, NULL, NULL);
|
|
||||||
break;
|
|
||||||
case ACCESS:
|
|
||||||
access = name;
|
access = name;
|
||||||
name = strchr(name, ':');
|
name = strchr(name, ':');
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
@ -99,15 +92,18 @@ int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
|
|||||||
do
|
do
|
||||||
name++;
|
name++;
|
||||||
while (*name == ' ' && *name != '\0');
|
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, "geometry");
|
||||||
json_reader_read_member(reader, "coordinates");
|
json_reader_read_member(reader, "coordinates");
|
||||||
|
if (layer_type == STREET) // For streets, this means elevation
|
||||||
z_last = 0; // By default, let's assume height 0
|
z_last = 0; // By default, let's assume height 0
|
||||||
|
else if (layer_type == ACCESS) // For access, it's the relative speed as well
|
||||||
|
z_last = 10; // 10 percent
|
||||||
|
else // For trainlines, z means relative speed to walking
|
||||||
|
z_last = 1000; // 2 times faster than walking
|
||||||
|
layer_name = name;
|
||||||
|
layer = dijkstra_layer_new_to_list(solver, layer_type, layer_name, access);
|
||||||
if (json_reader_is_array(reader)) {
|
if (json_reader_is_array(reader)) {
|
||||||
j_max = json_reader_count_elements(reader);
|
j_max = json_reader_count_elements(reader);
|
||||||
for (j = 0; j < j_max; j++) {
|
for (j = 0; j < j_max; j++) {
|
||||||
@ -134,8 +130,8 @@ int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
|
|||||||
x_last, y_last,
|
x_last, y_last,
|
||||||
x, y,
|
x, y,
|
||||||
z, z_last,
|
z, z_last,
|
||||||
|
layer,
|
||||||
name,
|
name,
|
||||||
net_meta,
|
|
||||||
DIJKSTRA_WEIGHT_AUTO);
|
DIJKSTRA_WEIGHT_AUTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include "dijkstragraph.h"
|
#include "dijkstragraph.h"
|
||||||
|
|
||||||
int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
|
int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
|
||||||
char *filename,
|
char *filename, char *type);
|
||||||
char *type);
|
|
||||||
|
|
||||||
#endif // GEOJSON_H
|
#endif // GEOJSON_H
|
||||||
|
53
src/main.c
53
src/main.c
@ -2,6 +2,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "dijkstragraph.h"
|
#include "dijkstragraph.h"
|
||||||
#include "dijkstrasearch.h"
|
#include "dijkstrasearch.h"
|
||||||
@ -12,18 +13,33 @@
|
|||||||
struct dijkstra_node *start;
|
struct dijkstra_node *start;
|
||||||
struct dijkstra_node *dest;
|
struct dijkstra_node *dest;
|
||||||
|
|
||||||
|
void add_test_map(struct dijkstra_solver *solver)
|
||||||
|
{
|
||||||
|
dijkstra_path_new_to_list(solver,
|
||||||
|
5,0,
|
||||||
|
5,10,
|
||||||
|
0,0,
|
||||||
|
NULL,
|
||||||
|
"Vertical",
|
||||||
|
1);
|
||||||
|
|
||||||
|
dijkstra_path_new_to_list(solver,
|
||||||
|
0,5,
|
||||||
|
10,5,
|
||||||
|
0,0,
|
||||||
|
NULL,
|
||||||
|
"Horizontal",
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
|
||||||
void help(const char *exec)
|
void help(const char *exec)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Usage: %s [OPTION] [TYPE:FILE]...\n"
|
"Usage: %s [OPTION] [FILE]...\n"
|
||||||
"Start the lifo-dijkstraserv routing server.\n\n"
|
"Start the lifo-dijkstraserv routing server.\n\n"
|
||||||
"Available options:\n"
|
|
||||||
" -s\tset output to silent\n"
|
" -s\tset output to silent\n"
|
||||||
" -v\tincrease verbosity. Maybe used multiple times.\n"
|
" -v\tincrease verbosity. Maybe used multiple times.\n"
|
||||||
" -p\tport number (default 6802)\n\n"
|
" -p\tport number (default 6802)\n",
|
||||||
"TYPE can be any of:\n"
|
|
||||||
" street (default), trainline, access\n\n"
|
|
||||||
"At least one GeoJson FILE must be presented.\n",
|
|
||||||
exec);
|
exec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,11 +53,13 @@ int main(int argc, char *argv[])
|
|||||||
GList *l = NULL;
|
GList *l = NULL;
|
||||||
struct dijkstra_node *node;
|
struct dijkstra_node *node;
|
||||||
struct dijkstra_path *path;
|
struct dijkstra_path *path;
|
||||||
char *file_name, *file_type;
|
struct dijkstra_layer *layer;
|
||||||
|
|
||||||
int port = 6802;
|
int port = 6802;
|
||||||
struct dijkstra_serv *serv;
|
struct dijkstra_serv *serv;
|
||||||
|
|
||||||
|
char *file_name, *file_type;
|
||||||
|
|
||||||
/* Init stuff */
|
/* Init stuff */
|
||||||
set_log_level(LL_DEBUG);
|
set_log_level(LL_DEBUG);
|
||||||
|
|
||||||
@ -56,7 +74,7 @@ int main(int argc, char *argv[])
|
|||||||
set_log_level(0);
|
set_log_level(0);
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
port = atoi(optarg);
|
port = atoi(argv[i]);
|
||||||
break;
|
break;
|
||||||
case ':':
|
case ':':
|
||||||
case '?':
|
case '?':
|
||||||
@ -84,7 +102,7 @@ int main(int argc, char *argv[])
|
|||||||
file_name = strchr(argv[i], ':');
|
file_name = strchr(argv[i], ':');
|
||||||
if (!file_name) {
|
if (!file_name) {
|
||||||
file_name = argv[i];
|
file_name = argv[i];
|
||||||
file_type = "street";
|
file_type = "streets";
|
||||||
} else {
|
} else {
|
||||||
*file_name = '\0';
|
*file_name = '\0';
|
||||||
file_name++;
|
file_name++;
|
||||||
@ -94,17 +112,26 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (should_report(LL_NOISY)) {
|
if (should_report(LL_NOISY)) {
|
||||||
|
for (l = solver->layers; l != NULL; l = l->next) {
|
||||||
|
layer = (struct dijkstra_layer*) l->data;
|
||||||
|
fprintf(stderr, "Layer %p: %d : %s", layer, layer->type, layer->name);
|
||||||
|
if (layer->type == ACCESS)
|
||||||
|
fprintf(stderr, " (access to %s)", layer->access);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
for (l = solver->nodes; l != NULL; l = l->next) {
|
for (l = solver->nodes; l != NULL; l = l->next) {
|
||||||
node = (struct dijkstra_node*) l->data;
|
node = (struct dijkstra_node*) l->data;
|
||||||
fprintf(stderr, "Node %5d @%p: %f,\t%f [%d paths]\n", node->uid, node, node->position.x, node->position.y, g_list_length(node->paths));
|
fprintf(stderr, "Node %5d %d@%p: %f,\t%f [%d paths]\n", node->uid, node->layer->type, node, node->position.x, node->position.y, g_list_length(node->paths));
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
for (l = solver->paths; l != NULL; l = l->next) {
|
for (l = solver->paths; l != NULL; l = l->next) {
|
||||||
path = (struct dijkstra_path*) l->data;
|
path = (struct dijkstra_path*) l->data;
|
||||||
fprintf(stderr, "Path %p: %5d (%f,%f) -> %5d (%f,%f) cost %d \t\"%s\"\n", path,
|
fprintf(stderr, "Path %p: %5d (%d,%f,%f,%d) -> %5d (%d,%f,%f,%d) cost %d \t\"%s\"\n", path,
|
||||||
path->source->uid, path->source->position.x, path->source->position.y,
|
path->source->uid, path->source->layer->type, path->source->position.x, path->source->position.y, path->source->position.z,
|
||||||
path->destination->uid, path->destination->position.x, path->destination->position.y,
|
path->destination->uid, path->destination->layer->type, path->destination->position.x, path->destination->position.y, path->destination->position.z,
|
||||||
path->weight,
|
path->weight,
|
||||||
path->name);
|
path->name);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user