Compare commits

..

1 Commits

Author SHA1 Message Date
Markus Koch 724a663a34 wip: bound for refactoring 2021-03-13 13:38:25 +01:00
5 changed files with 92 additions and 50 deletions

View File

@ -12,7 +12,6 @@ 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->position.z == node_b->position.z); same &= (node_a->position.z == node_b->position.z);
@ -29,8 +28,7 @@ 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, int uid)
struct dijkstra_net_meta *net_meta)
{ {
struct dijkstra_node *node; struct dijkstra_node *node;
@ -40,7 +38,6 @@ struct dijkstra_node *dijkstra_node_new(float x,
node->position.y = y; node->position.y = y;
node->position.z = z; node->position.z = z;
node->uid = uid; node->uid = uid;
node->net_meta = net_meta;
node->paths = NULL; node->paths = NULL;
} }
@ -74,8 +71,7 @@ struct dijkstra_node *dijkstra_node_exists(GList *list,
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_node *node; struct dijkstra_node *node;
struct dijkstra_node *found; struct dijkstra_node *found;
@ -83,7 +79,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, uid);
if (!node) if (!node)
return NULL; return NULL;
@ -180,7 +176,10 @@ dijkstra_cost dijkstra_get_weight_from_distance(struct dijkstra_node *node_a,
switch (net_type) { switch (net_type) {
case TRAINLINE: case TRAINLINE:
scale = 10.0; scale = 5.0;
break;
case ACCESS:
scale = 0.5;
break; break;
default: default:
scale = 1.0; scale = 1.0;
@ -287,6 +286,7 @@ int dijkstra_path_intersect(struct dijkstra_solver *solver,
struct dijkstra_node *disconnected_node; struct dijkstra_node *disconnected_node;
struct dijkstra_path *access_path = NULL; struct dijkstra_path *access_path = NULL;
struct dijkstra_path *target_path = NULL; struct dijkstra_path *target_path = NULL;
struct dijkstra_net_meta_access *net_meta_access = 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;
@ -309,8 +309,9 @@ int dijkstra_path_intersect(struct dijkstra_solver *solver,
} }
if (access_path) { if (access_path) {
net_meta_access = (struct dijkstra_net_meta_access *) access_path->net_meta->type_data;
if (target_path->net_meta->type != STREET && if (target_path->net_meta->type != STREET &&
!strstr(access_path->net_meta->access, target_path->name)) { !strstr(net_meta_access->access, target_path->name)) {
return 0; // Don't intersect if access != name of target return 0; // Don't intersect if access != name of target
} }
} else { } else {
@ -321,9 +322,6 @@ int dijkstra_path_intersect(struct dijkstra_solver *solver,
return 0; // Never intersect trainlines (apart from with access types) 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 // Check height
p0_z = path_a->source->position.z; p0_z = path_a->source->position.z;
p1_z = path_a->destination->position.z; p1_z = path_a->destination->position.z;
@ -360,7 +358,7 @@ int dijkstra_path_intersect(struct dijkstra_solver *solver,
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_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, target_path->source->net_meta); node_new = dijkstra_node_new_to_list(&solver->nodes, i_x, i_y, i_z);
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);
@ -378,7 +376,8 @@ int dijkstra_path_intersect(struct dijkstra_solver *solver,
path_new->destination, path_new->destination,
path_new->net_meta->type); 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
@ -397,8 +396,6 @@ int dijkstra_path_intersect(struct dijkstra_solver *solver,
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); 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.
@ -441,8 +438,8 @@ 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);
n2 = dijkstra_node_new_to_list(&solver->nodes, x2, y2, z2, net_meta); n2 = dijkstra_node_new_to_list(&solver->nodes, x2, y2, z2);
path = dijkstra_path_new(name, n1, n2, weight, net_meta); path = dijkstra_path_new(name, n1, n2, weight, net_meta);
l_last = g_list_last(solver->paths); l_last = g_list_last(solver->paths);
@ -469,6 +466,42 @@ struct dijkstra_solver *dijkstra_solver_new()
return solver; return solver;
} }
struct dijkstra_net_meta_access *dijkstra_net_meta_access_new(char *access) {
struct dijkstra_net_meta_access *nma;
nma = malloc(sizeof(nma));
nma->access = strdup(access);
return nma;
}
void dijkstra_netmeta_free(struct dijkstra_net_meta *net_meta)
{
struct dijkstra_net_meta_access *nma;
struct dijkstra_net_meta_trainline *nmt;
nma = (struct dijkstra_net_meta_access *) net_meta->type_data;
nmt = (struct dijkstra_net_meta_trainline *) net_meta->type_data;
switch (net_meta->type) {
case ACCESS:
if (nma->access)
free(nma->access);
break;
case TRAINLINE:
if (nmt->start)
free(nmt->start);
if (nmt->end)
free(nmt->end);
break;
default:
break; // Nothing to do for other types
}
free(net_meta);
}
void dijkstra_solver_free(struct dijkstra_solver *solver) void dijkstra_solver_free(struct dijkstra_solver *solver)
{ {
GList *l; GList *l;
@ -496,9 +529,7 @@ void dijkstra_solver_free(struct dijkstra_solver *solver)
for (l = solver->net_metas; l != NULL; l = l->next) { for (l = solver->net_metas; l != NULL; l = l->next) {
net_meta = (struct dijkstra_net_meta*) l->data; net_meta = (struct dijkstra_net_meta*) l->data;
free(net_meta->name); free(net_meta->name);
if (net_meta->access) dijkstra_netmeta_free(net_meta);
free(net_meta->access);
free(net_meta);
} }
} }
@ -551,7 +582,7 @@ struct dijkstra_node *dijkstra_node_find_closest_node(struct dijkstra_solver *so
struct dijkstra_net_meta *dijkstra_net_meta_new(enum dijkstra_net_type net_type, struct dijkstra_net_meta *dijkstra_net_meta_new(enum dijkstra_net_type net_type,
char *name, char *name,
char *access) void *type_data)
{ {
struct dijkstra_net_meta *net_meta; struct dijkstra_net_meta *net_meta;
@ -559,10 +590,7 @@ struct dijkstra_net_meta *dijkstra_net_meta_new(enum dijkstra_net_type net_type,
if (net_meta) { if (net_meta) {
net_meta->type = net_type; net_meta->type = net_type;
net_meta->name = strdup(name); net_meta->name = strdup(name);
if (access) net_meta->type_data = type_data;
net_meta->access = strdup(access);
else
net_meta->access = NULL;
} }
return net_meta; return net_meta;
@ -581,10 +609,16 @@ struct dijkstra_net_meta *dijkstra_net_meta_new_to_list(struct dijkstra_solver *
for (l = solver->net_metas; l != NULL; l = l->next) { for (l = solver->net_metas; l != NULL; l = l->next) {
net_meta = l->data; net_meta = l->data;
if (net_meta->type == net_type && if (net_meta->type == net_type && !strcmp(net_meta->name, name)) {
!strcmp(net_meta->name, name) && switch (net_meta->type) {
(net_meta->access && (!strcmp(net_meta->access, access)))) { case ACCESS:
return net_meta; if (!strcmp(((struct dijkstra_net_meta_access *)net_meta->type_data)->access, access))
return net_meta;
break;
default:
return net_meta;
break;
}
} }
} }

View File

@ -23,10 +23,19 @@ struct position {
enum dijkstra_net_type {STREET, TRAINLINE, ACCESS}; enum dijkstra_net_type {STREET, TRAINLINE, ACCESS};
struct dijkstra_net_meta_access {
char *access;
};
struct dijkstra_net_meta_trainline {
char *start;
char *end;
};
struct dijkstra_net_meta { struct dijkstra_net_meta {
char *name; char *name;
enum dijkstra_net_type type; enum dijkstra_net_type type;
char *access; void *type_data;
}; };
struct dijkstra_path { struct dijkstra_path {
@ -39,7 +48,6 @@ struct dijkstra_path {
struct dijkstra_node { struct dijkstra_node {
struct position position; struct position position;
struct dijkstra_net_meta *net_meta;
GList *paths; GList *paths;
@ -78,7 +86,6 @@ struct dijkstra_net_meta *dijkstra_net_meta_new_to_list(struct dijkstra_solver *
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);
#endif // DIJKSTRAGRAPH_H #endif // DIJKSTRAGRAPH_H

View File

@ -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);

View File

@ -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;

View File

@ -27,6 +27,8 @@ int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
enum dijkstra_net_type net_type; enum dijkstra_net_type net_type;
struct dijkstra_net_meta *net_meta; struct dijkstra_net_meta *net_meta;
void *type_data = NULL;
struct dijkstra_net_meta_access *net_meta_access = NULL;
struct _stats { struct _stats {
int nodes; int nodes;
@ -63,7 +65,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);
@ -78,19 +79,23 @@ int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
json_reader_read_member(reader, "name"); json_reader_read_member(reader, "name");
name = strdup(json_reader_get_string_value(reader)); name = strdup(json_reader_get_string_value(reader));
json_reader_end_member(reader); // name json_reader_end_member(reader); // name
json_reader_end_member(reader); // properties
switch (net_type) { switch (net_type) {
case STREET: case TRAINLINE:
if (!net_meta) json_reader_read_member(reader, "start");
net_meta = dijkstra_net_meta_new_to_list(solver, net_type, NULL, NULL); name = strdup(json_reader_get_string_value(reader));
json_reader_end_member(reader); // name
break; break;
case ACCESS: case ACCESS:
net_meta_access = netmeta;
// TODO: problem, I only know whether to alloc this when I have called new_to_list.....
// I'll deal with this some other day.
access = name; access = name;
name = strchr(name, ':'); name = strchr(name, ':');
if (name == NULL) { if (name == NULL) {
report(LL_ERROR, report(LL_ERROR,
"Invalid name for accesss. '%s'", "Invalid name for access. '%s'",
access); access);
g_object_unref(reader); g_object_unref(reader);
continue; continue;
@ -99,15 +104,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; break;
default:
break; // Other types have no special fields
} }
json_reader_end_member(reader); // properties
json_reader_read_member(reader, "geometry"); json_reader_read_member(reader, "geometry");
json_reader_read_member(reader, "coordinates"); json_reader_read_member(reader, "coordinates");
z_last = 0; // By default, let's assume height 0 z_last = 0; // By default, let's assume height 0
net_meta = dijkstra_net_meta_new_to_list(solver, net_type, name, type_data);
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++) {