Clean up code
This commit is contained in:
parent
25ccfc5df5
commit
0d2945d76f
@ -4,6 +4,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#define FP_THRESHOLD 0.01
|
#define FP_THRESHOLD 0.01
|
||||||
|
|
||||||
int dijkstra_node_same (struct dijkstra_node *node_a,
|
int dijkstra_node_same (struct dijkstra_node *node_a,
|
||||||
struct dijkstra_node *node_b)
|
struct dijkstra_node *node_b)
|
||||||
{
|
{
|
||||||
@ -16,6 +17,27 @@ int dijkstra_node_same (struct dijkstra_node *node_a,
|
|||||||
return same;
|
return same;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief dijkstra_node_new creates a new dijkstra_node
|
||||||
|
* \param x x position
|
||||||
|
* \param y y position
|
||||||
|
* \return a new dijkstra node or NULL. Needs to be freed manually.
|
||||||
|
*/
|
||||||
|
struct dijkstra_node *dijkstra_node_new(float x,
|
||||||
|
float y)
|
||||||
|
{
|
||||||
|
struct dijkstra_node *node;
|
||||||
|
|
||||||
|
node = malloc(sizeof(*node));
|
||||||
|
if (node) {
|
||||||
|
node->position.x = x;
|
||||||
|
node->position.y = y;
|
||||||
|
node->paths = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
struct dijkstra_node *dijkstra_node_exists(GList *list,
|
struct dijkstra_node *dijkstra_node_exists(GList *list,
|
||||||
struct dijkstra_node *node)
|
struct dijkstra_node *node)
|
||||||
{
|
{
|
||||||
@ -125,6 +147,29 @@ struct dijkstra_path *dijkstra_path_dup_shallow(struct dijkstra_path *path)
|
|||||||
return dup;
|
return dup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief dijkstra_path_new creates a new dijkstra_path between two nodes.
|
||||||
|
* \param name the name of the path (pointer is not copied and must stay valid!)
|
||||||
|
* \return a new dijkstra path or NULL. Needs to be freed manually.
|
||||||
|
*/
|
||||||
|
struct dijkstra_path *dijkstra_path_new(char *name,
|
||||||
|
struct dijkstra_node *source,
|
||||||
|
struct dijkstra_node *destination,
|
||||||
|
dijkstra_cost weight)
|
||||||
|
{
|
||||||
|
struct dijkstra_path *path;
|
||||||
|
|
||||||
|
path = malloc(sizeof(*path));
|
||||||
|
if (path) {
|
||||||
|
path->name = name;
|
||||||
|
path->weight = weight;
|
||||||
|
|
||||||
|
dijkstra_connect_nodes_to_path(source, destination, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
struct dijkstra_node *dijkstra_disconnect_node_from_path(struct dijkstra_path *path,
|
struct dijkstra_node *dijkstra_disconnect_node_from_path(struct dijkstra_path *path,
|
||||||
struct dijkstra_node *node,
|
struct dijkstra_node *node,
|
||||||
int ref_only)
|
int ref_only)
|
||||||
@ -142,8 +187,7 @@ struct dijkstra_node *dijkstra_disconnect_node_from_path(struct dijkstra_path *p
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dijkstra_path_intersect(GList **nodes,
|
int dijkstra_path_intersect(struct dijkstra_solver *solver,
|
||||||
GList **paths,
|
|
||||||
struct dijkstra_path *path_a,
|
struct dijkstra_path *path_a,
|
||||||
struct dijkstra_path *path_b)
|
struct dijkstra_path *path_b)
|
||||||
{
|
{
|
||||||
@ -190,11 +234,11 @@ int dijkstra_path_intersect(GList **nodes,
|
|||||||
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);
|
||||||
|
|
||||||
node_new = dijkstra_node_new_to_list(nodes, i_x, i_y, &is_new);
|
node_new = dijkstra_node_new_to_list(&solver->nodes, i_x, i_y, &is_new);
|
||||||
|
|
||||||
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);
|
||||||
*paths = g_list_append(*paths, (gpointer) path_new);
|
solver->paths = g_list_append(solver->paths, (gpointer) path_new);
|
||||||
|
|
||||||
dijkstra_disconnect_node_from_path(path_a, path_a->destination, 1);
|
dijkstra_disconnect_node_from_path(path_a, path_a->destination, 1);
|
||||||
dijkstra_connect_destination_node_to_path(node_new, path_a);
|
dijkstra_connect_destination_node_to_path(node_new, path_a);
|
||||||
@ -204,7 +248,7 @@ int dijkstra_path_intersect(GList **nodes,
|
|||||||
// Now do the same thing for path b
|
// Now do the same thing for path b
|
||||||
if (node_new != path_b->source && node_new != path_b->destination) {
|
if (node_new != path_b->source && node_new != path_b->destination) {
|
||||||
path_new = dijkstra_path_dup_shallow(path_b);
|
path_new = dijkstra_path_dup_shallow(path_b);
|
||||||
*paths = g_list_append(*paths, (gpointer) path_new);
|
solver->paths = g_list_append(solver->paths, (gpointer) path_new);
|
||||||
dijkstra_disconnect_node_from_path(path_b, path_b->destination, 1);
|
dijkstra_disconnect_node_from_path(path_b, path_b->destination, 1);
|
||||||
dijkstra_connect_destination_node_to_path(node_new, path_b);
|
dijkstra_connect_destination_node_to_path(node_new, path_b);
|
||||||
dijkstra_connect_source_node_to_path(node_new, path_new);
|
dijkstra_connect_source_node_to_path(node_new, path_new);
|
||||||
@ -215,8 +259,7 @@ int dijkstra_path_intersect(GList **nodes,
|
|||||||
return 0; // No collision
|
return 0; // No collision
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dijkstra_path *dijkstra_path_new_to_list(GList **nodes,
|
struct dijkstra_path *dijkstra_path_new_to_list(struct dijkstra_solver *solver,
|
||||||
GList **paths,
|
|
||||||
float x1,
|
float x1,
|
||||||
float y1,
|
float y1,
|
||||||
float x2,
|
float x2,
|
||||||
@ -229,16 +272,16 @@ struct dijkstra_path *dijkstra_path_new_to_list(GList **nodes,
|
|||||||
struct dijkstra_path *existing_path;
|
struct dijkstra_path *existing_path;
|
||||||
GList *l, *l_last;
|
GList *l, *l_last;
|
||||||
|
|
||||||
n1 = dijkstra_node_new_to_list(nodes, x1, y1, NULL);
|
n1 = dijkstra_node_new_to_list(&solver->nodes, x1, y1, NULL);
|
||||||
n2 = dijkstra_node_new_to_list(nodes, x2, y2, NULL);
|
n2 = dijkstra_node_new_to_list(&solver->nodes, x2, y2, NULL);
|
||||||
path = dijkstra_path_new(name, n1, n2, weight);
|
path = dijkstra_path_new(name, n1, n2, weight);
|
||||||
|
|
||||||
l_last = g_list_last(*paths);
|
l_last = g_list_last(solver->paths);
|
||||||
*paths = g_list_append(*paths, (gpointer) path);
|
solver->paths = g_list_append(solver->paths, (gpointer) path);
|
||||||
|
|
||||||
for (l = *paths; l != NULL; l = l->next) {
|
for (l = solver->paths; l != NULL; l = l->next) {
|
||||||
existing_path = (struct dijkstra_path*) l->data;
|
existing_path = (struct dijkstra_path*) l->data;
|
||||||
dijkstra_path_intersect(nodes, paths, path, existing_path);
|
dijkstra_path_intersect(solver, path, existing_path);
|
||||||
if (l == l_last) /* Avoid testing newly added paths */
|
if (l == l_last) /* Avoid testing newly added paths */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -246,46 +289,39 @@ struct dijkstra_path *dijkstra_path_new_to_list(GList **nodes,
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
struct dijkstra_solver *dijkstra_solver_new()
|
||||||
* \brief dijkstra_node_new creates a new dijkstra_node
|
|
||||||
* \param x x position
|
|
||||||
* \param y y position
|
|
||||||
* \return a new dijkstra node or NULL. Needs to be freed manually.
|
|
||||||
*/
|
|
||||||
struct dijkstra_node *dijkstra_node_new(float x,
|
|
||||||
float y)
|
|
||||||
{
|
{
|
||||||
|
struct dijkstra_solver *solver;
|
||||||
|
|
||||||
|
solver = malloc(sizeof(*solver));
|
||||||
|
if (solver) {
|
||||||
|
solver->nodes = NULL;
|
||||||
|
solver->paths = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return solver;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dijkstra_solver_free(struct dijkstra_solver *solver)
|
||||||
|
{
|
||||||
|
GList *l;
|
||||||
|
struct dijkstra_path *path;
|
||||||
struct dijkstra_node *node;
|
struct dijkstra_node *node;
|
||||||
|
|
||||||
node = malloc(sizeof(*node));
|
// Free memory
|
||||||
if (node) {
|
for (l = solver->paths; l != NULL; l = l->next) {
|
||||||
node->position.x = x;
|
path = (struct dijkstra_path*) l->data;
|
||||||
node->position.y = y;
|
// TODO: free(path->name);
|
||||||
node->paths = NULL;
|
// Currently, we reuse the existing memory block when for the
|
||||||
|
// name when cloning streets. As such, clearing it here will
|
||||||
|
// cause a double free if the street has been split.
|
||||||
|
free(path);
|
||||||
}
|
}
|
||||||
|
g_list_free(solver->paths);
|
||||||
|
|
||||||
return node;
|
for (l = solver->nodes; l != NULL; l = l->next) {
|
||||||
}
|
node = (struct dijkstra_node*) l->data;
|
||||||
|
free(node);
|
||||||
/*!
|
|
||||||
* \brief dijkstra_path_new creates a new dijkstra_path between two nodes.
|
|
||||||
* \param name the name of the path (pointer is not copied and must stay valid!)
|
|
||||||
* \return a new dijkstra path or NULL. Needs to be freed manually.
|
|
||||||
*/
|
|
||||||
struct dijkstra_path *dijkstra_path_new(char *name,
|
|
||||||
struct dijkstra_node *source,
|
|
||||||
struct dijkstra_node *destination,
|
|
||||||
dijkstra_cost weight)
|
|
||||||
{
|
|
||||||
struct dijkstra_path *path;
|
|
||||||
|
|
||||||
path = malloc(sizeof(*path));
|
|
||||||
if (path) {
|
|
||||||
path->name = name;
|
|
||||||
path->weight = weight;
|
|
||||||
|
|
||||||
dijkstra_connect_nodes_to_path(source, destination, path);
|
|
||||||
}
|
}
|
||||||
|
g_list_free(solver->nodes);
|
||||||
return path;
|
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,16 @@
|
|||||||
|
|
||||||
typedef int dijkstra_cost;
|
typedef int dijkstra_cost;
|
||||||
|
|
||||||
|
struct dijkstra_solver {
|
||||||
|
GList *nodes;
|
||||||
|
GList *paths;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dijkstra_state {
|
||||||
|
dijkstra_cost cost;
|
||||||
|
int visited;
|
||||||
|
};
|
||||||
|
|
||||||
struct position {
|
struct position {
|
||||||
float x;
|
float x;
|
||||||
float y;
|
float y;
|
||||||
@ -22,27 +32,18 @@ struct dijkstra_node {
|
|||||||
|
|
||||||
GList *paths;
|
GList *paths;
|
||||||
|
|
||||||
dijkstra_cost cost;
|
int uid;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dijkstra_node *dijkstra_node_new(float x,
|
struct dijkstra_path *dijkstra_path_new_to_list(struct dijkstra_solver *solver,
|
||||||
float y);
|
|
||||||
struct dijkstra_path *dijkstra_path_new(char *name,
|
|
||||||
struct dijkstra_node *source,
|
|
||||||
struct dijkstra_node *destination,
|
|
||||||
dijkstra_cost weight);
|
|
||||||
|
|
||||||
int dijkstra_path_intersect(GList **nodes,
|
|
||||||
GList **paths,
|
|
||||||
struct dijkstra_path *path_a,
|
|
||||||
struct dijkstra_path *path_b);
|
|
||||||
|
|
||||||
struct dijkstra_path *dijkstra_path_new_to_list(GList **nodes,
|
|
||||||
GList **paths,
|
|
||||||
float x1,
|
float x1,
|
||||||
float y1,
|
float y1,
|
||||||
float x2,
|
float x2,
|
||||||
float y2,
|
float y2,
|
||||||
char *name,
|
char *name,
|
||||||
dijkstra_cost weight);
|
dijkstra_cost weight);
|
||||||
|
|
||||||
|
struct dijkstra_solver *dijkstra_solver_new();
|
||||||
|
void dijkstra_solver_free(struct dijkstra_solver *solver);
|
||||||
|
|
||||||
#endif // DIJKSTRASEARCH_H
|
#endif // DIJKSTRASEARCH_H
|
||||||
|
@ -6,8 +6,7 @@
|
|||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
#include <json-glib/json-glib.h>
|
#include <json-glib/json-glib.h>
|
||||||
|
|
||||||
int add_geojson_to_dijkstra(GList **nodes,
|
int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
|
||||||
GList **paths,
|
|
||||||
char *filename)
|
char *filename)
|
||||||
{
|
{
|
||||||
JsonParser *parser;
|
JsonParser *parser;
|
||||||
@ -81,7 +80,7 @@ int add_geojson_to_dijkstra(GList **nodes,
|
|||||||
|
|
||||||
if (j > 0) {
|
if (j > 0) {
|
||||||
stats.paths++;
|
stats.paths++;
|
||||||
dijkstra_path_new_to_list(nodes, paths,
|
dijkstra_path_new_to_list(solver,
|
||||||
x_last, y_last,
|
x_last, y_last,
|
||||||
x, y,
|
x, y,
|
||||||
name, 1);
|
name, 1);
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
#define GEOJSON_H
|
#define GEOJSON_H
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
#include "dijkstrasearch.h"
|
||||||
|
|
||||||
int add_geojson_to_dijkstra(GList **nodes,
|
int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
|
||||||
GList **paths,
|
|
||||||
char *filename);
|
char *filename);
|
||||||
|
|
||||||
#endif // GEOJSON_H
|
#endif // GEOJSON_H
|
||||||
|
73
src/main.c
73
src/main.c
@ -7,18 +7,15 @@
|
|||||||
#include "geojson.h"
|
#include "geojson.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
|
||||||
void add_test_map(GList **nodes,
|
void add_test_map(struct dijkstra_solver *solver)
|
||||||
GList **paths)
|
|
||||||
{
|
{
|
||||||
dijkstra_path_new_to_list(nodes,
|
dijkstra_path_new_to_list(solver,
|
||||||
paths,
|
|
||||||
0,0,
|
0,0,
|
||||||
0,10,
|
0,10,
|
||||||
"Vertical",
|
"Vertical",
|
||||||
1);
|
1);
|
||||||
|
|
||||||
dijkstra_path_new_to_list(nodes,
|
dijkstra_path_new_to_list(solver,
|
||||||
paths,
|
|
||||||
0,5,
|
0,5,
|
||||||
10,5,
|
10,5,
|
||||||
"Horizontal",
|
"Horizontal",
|
||||||
@ -41,8 +38,7 @@ int main(int argc, char *argv[])
|
|||||||
int opt;
|
int opt;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
GList *nodes = NULL;
|
struct dijkstra_solver *solver;
|
||||||
GList *paths = NULL;
|
|
||||||
|
|
||||||
GList *l = NULL;
|
GList *l = NULL;
|
||||||
struct dijkstra_node *node;
|
struct dijkstra_node *node;
|
||||||
@ -53,20 +49,20 @@ int main(int argc, char *argv[])
|
|||||||
// Process arguments
|
// Process arguments
|
||||||
while((opt = getopt(argc, argv, "vs")) != -1) {
|
while((opt = getopt(argc, argv, "vs")) != -1) {
|
||||||
switch(opt)
|
switch(opt)
|
||||||
{
|
{
|
||||||
case 'v':
|
case 'v':
|
||||||
set_log_level(get_log_level() + 1);
|
set_log_level(get_log_level() + 1);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
set_log_level(0);
|
set_log_level(0);
|
||||||
break;
|
break;
|
||||||
case ':':
|
case ':':
|
||||||
case '?':
|
case '?':
|
||||||
help(argv[0]);
|
help(argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind == argc) {
|
if (optind == argc) {
|
||||||
@ -74,21 +70,27 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
solver = dijkstra_solver_new();
|
||||||
|
if (!solver) {
|
||||||
|
report(LL_CRITICAL, "Memory allocation failure.");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse file list */
|
/* Parse file list */
|
||||||
for (i = optind; i < argc; ++i) {
|
for (i = optind; i < argc; ++i) {
|
||||||
add_geojson_to_dijkstra(&nodes, &paths, argv[i]);
|
add_geojson_to_dijkstra(solver, argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add_test_map(&nodes, &paths);
|
// add_test_map(&nodes, &paths);
|
||||||
|
|
||||||
if (should_report(LL_NOISY)) {
|
if (should_report(LL_NOISY)) {
|
||||||
for (l = 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;
|
||||||
printf("Node %p: %f,\t%f [%d paths]\n", node, node->position.x, node->position.y, g_list_length(node->paths));
|
printf("Node %p: %f,\t%f [%d paths]\n", node, node->position.x, node->position.y, g_list_length(node->paths));
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
for (l = 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;
|
||||||
printf("Path %p: %p (%f,%f) -> %p (%f,%f) \t\"%s\"\n", path,
|
printf("Path %p: %p (%f,%f) -> %p (%f,%f) \t\"%s\"\n", path,
|
||||||
path->source, path->source->position.x, path->source->position.y,
|
path->source, path->source->position.x, path->source->position.y,
|
||||||
@ -99,25 +101,10 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
report(LL_INFO, "Created graph with %d nodes and %d paths.",
|
report(LL_INFO, "Created graph with %d nodes and %d paths.",
|
||||||
g_list_length(nodes),
|
g_list_length(solver->nodes),
|
||||||
g_list_length(paths));
|
g_list_length(solver->paths));
|
||||||
|
|
||||||
// Free memory
|
dijkstra_solver_free(solver);
|
||||||
for (l = paths; l != NULL; l = l->next) {
|
|
||||||
path = (struct dijkstra_path*) l->data;
|
|
||||||
// TODO: free(path->name);
|
|
||||||
// Currently, we reuse the existing memory block when for the
|
|
||||||
// name when cloning streets. As such, clearing it here will
|
|
||||||
// cause a double free if the street has been split.
|
|
||||||
free(path);
|
|
||||||
}
|
|
||||||
g_list_free(paths);
|
|
||||||
|
|
||||||
for (l = nodes; l != NULL; l = l->next) {
|
|
||||||
node = (struct dijkstra_node*) l->data;
|
|
||||||
free(node);
|
|
||||||
}
|
|
||||||
g_list_free(nodes);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user