Clean up code
This commit is contained in:
		
							parent
							
								
									25ccfc5df5
								
							
						
					
					
						commit
						0d2945d76f
					
				@ -4,6 +4,7 @@
 | 
			
		||||
#include <math.h>
 | 
			
		||||
 | 
			
		||||
#define FP_THRESHOLD 0.01
 | 
			
		||||
 | 
			
		||||
int dijkstra_node_same (struct dijkstra_node *node_a,
 | 
			
		||||
			struct dijkstra_node *node_b)
 | 
			
		||||
{
 | 
			
		||||
@ -16,6 +17,27 @@ int dijkstra_node_same (struct dijkstra_node *node_a,
 | 
			
		||||
	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 *node)
 | 
			
		||||
{
 | 
			
		||||
@ -125,6 +147,29 @@ struct dijkstra_path *dijkstra_path_dup_shallow(struct dijkstra_path *path)
 | 
			
		||||
	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 *node,
 | 
			
		||||
							 int ref_only)
 | 
			
		||||
@ -142,8 +187,7 @@ struct dijkstra_node *dijkstra_disconnect_node_from_path(struct dijkstra_path *p
 | 
			
		||||
	return node;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dijkstra_path_intersect(GList **nodes,
 | 
			
		||||
			    GList **paths,
 | 
			
		||||
int dijkstra_path_intersect(struct dijkstra_solver *solver,
 | 
			
		||||
			    struct dijkstra_path *path_a,
 | 
			
		||||
			    struct dijkstra_path *path_b)
 | 
			
		||||
{
 | 
			
		||||
@ -190,11 +234,11 @@ int dijkstra_path_intersect(GList **nodes,
 | 
			
		||||
		i_x = p0_x + (t * s1_x);
 | 
			
		||||
		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) {
 | 
			
		||||
			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_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
 | 
			
		||||
		if (node_new != path_b->source && node_new != path_b->destination) {
 | 
			
		||||
			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_connect_destination_node_to_path(node_new, path_b);
 | 
			
		||||
			dijkstra_connect_source_node_to_path(node_new, path_new);
 | 
			
		||||
@ -215,8 +259,7 @@ int dijkstra_path_intersect(GList **nodes,
 | 
			
		||||
	return 0; // No collision
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct dijkstra_path *dijkstra_path_new_to_list(GList **nodes,
 | 
			
		||||
						GList **paths,
 | 
			
		||||
struct dijkstra_path *dijkstra_path_new_to_list(struct dijkstra_solver *solver,
 | 
			
		||||
						float x1,
 | 
			
		||||
						float y1,
 | 
			
		||||
						float x2,
 | 
			
		||||
@ -229,16 +272,16 @@ struct dijkstra_path *dijkstra_path_new_to_list(GList **nodes,
 | 
			
		||||
	struct dijkstra_path *existing_path;
 | 
			
		||||
	GList *l, *l_last;
 | 
			
		||||
 | 
			
		||||
	n1 = dijkstra_node_new_to_list(nodes, x1, y1, NULL);
 | 
			
		||||
	n2 = dijkstra_node_new_to_list(nodes, x2, y2, NULL);
 | 
			
		||||
	n1 = dijkstra_node_new_to_list(&solver->nodes, x1, y1, NULL);
 | 
			
		||||
	n2 = dijkstra_node_new_to_list(&solver->nodes, x2, y2, NULL);
 | 
			
		||||
	path = dijkstra_path_new(name, n1, n2, weight);
 | 
			
		||||
 | 
			
		||||
	l_last = g_list_last(*paths);
 | 
			
		||||
	*paths = g_list_append(*paths, (gpointer) path);
 | 
			
		||||
	l_last = g_list_last(solver->paths);
 | 
			
		||||
	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;
 | 
			
		||||
		dijkstra_path_intersect(nodes, paths, path, existing_path);
 | 
			
		||||
		dijkstra_path_intersect(solver, path, existing_path);
 | 
			
		||||
		if (l == l_last) /* Avoid testing newly added paths */
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
@ -246,46 +289,39 @@ struct dijkstra_path *dijkstra_path_new_to_list(GList **nodes,
 | 
			
		||||
	return path;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
 * \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 *dijkstra_solver_new()
 | 
			
		||||
{
 | 
			
		||||
	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;
 | 
			
		||||
 | 
			
		||||
	node = malloc(sizeof(*node));
 | 
			
		||||
	if (node) {
 | 
			
		||||
		node->position.x = x;
 | 
			
		||||
		node->position.y = y;
 | 
			
		||||
		node->paths = NULL;
 | 
			
		||||
	// Free memory
 | 
			
		||||
	for (l = solver->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(solver->paths);
 | 
			
		||||
 | 
			
		||||
	return 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);
 | 
			
		||||
	for (l = solver->nodes; l != NULL; l = l->next) {
 | 
			
		||||
		node = (struct dijkstra_node*) l->data;
 | 
			
		||||
		free(node);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return path;
 | 
			
		||||
	g_list_free(solver->nodes);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,16 @@
 | 
			
		||||
 | 
			
		||||
typedef int dijkstra_cost;
 | 
			
		||||
 | 
			
		||||
struct dijkstra_solver {
 | 
			
		||||
	GList *nodes;
 | 
			
		||||
	GList *paths;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dijkstra_state {
 | 
			
		||||
	dijkstra_cost cost;
 | 
			
		||||
	int visited;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct position {
 | 
			
		||||
	float x;
 | 
			
		||||
	float y;
 | 
			
		||||
@ -22,27 +32,18 @@ struct dijkstra_node {
 | 
			
		||||
 | 
			
		||||
	GList *paths;
 | 
			
		||||
 | 
			
		||||
	dijkstra_cost cost;
 | 
			
		||||
	int uid;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dijkstra_node *dijkstra_node_new(float x,
 | 
			
		||||
					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,
 | 
			
		||||
struct dijkstra_path *dijkstra_path_new_to_list(struct dijkstra_solver *solver,
 | 
			
		||||
						float x1,
 | 
			
		||||
						float y1,
 | 
			
		||||
						float x2,
 | 
			
		||||
						float y2,
 | 
			
		||||
						char *name,
 | 
			
		||||
						dijkstra_cost weight);
 | 
			
		||||
 | 
			
		||||
struct dijkstra_solver *dijkstra_solver_new();
 | 
			
		||||
void dijkstra_solver_free(struct dijkstra_solver *solver);
 | 
			
		||||
 | 
			
		||||
#endif // DIJKSTRASEARCH_H
 | 
			
		||||
 | 
			
		||||
@ -6,8 +6,7 @@
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <json-glib/json-glib.h>
 | 
			
		||||
 | 
			
		||||
int add_geojson_to_dijkstra(GList **nodes,
 | 
			
		||||
			    GList **paths,
 | 
			
		||||
int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
 | 
			
		||||
			    char *filename)
 | 
			
		||||
{
 | 
			
		||||
	JsonParser *parser;
 | 
			
		||||
@ -81,7 +80,7 @@ int add_geojson_to_dijkstra(GList **nodes,
 | 
			
		||||
 | 
			
		||||
							if (j > 0) {
 | 
			
		||||
								stats.paths++;
 | 
			
		||||
								dijkstra_path_new_to_list(nodes, paths,
 | 
			
		||||
								dijkstra_path_new_to_list(solver,
 | 
			
		||||
											  x_last, y_last,
 | 
			
		||||
											  x, y,
 | 
			
		||||
											  name, 1);
 | 
			
		||||
 | 
			
		||||
@ -2,9 +2,9 @@
 | 
			
		||||
#define GEOJSON_H
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include "dijkstrasearch.h"
 | 
			
		||||
 | 
			
		||||
int add_geojson_to_dijkstra(GList **nodes,
 | 
			
		||||
			    GList **paths,
 | 
			
		||||
int add_geojson_to_dijkstra(struct dijkstra_solver *solver,
 | 
			
		||||
			    char *filename);
 | 
			
		||||
 | 
			
		||||
#endif // GEOJSON_H
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										73
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								src/main.c
									
									
									
									
									
								
							@ -7,18 +7,15 @@
 | 
			
		||||
#include "geojson.h"
 | 
			
		||||
#include "logging.h"
 | 
			
		||||
 | 
			
		||||
void add_test_map(GList **nodes,
 | 
			
		||||
		  GList **paths)
 | 
			
		||||
void add_test_map(struct dijkstra_solver *solver)
 | 
			
		||||
{
 | 
			
		||||
	dijkstra_path_new_to_list(nodes,
 | 
			
		||||
				  paths,
 | 
			
		||||
	dijkstra_path_new_to_list(solver,
 | 
			
		||||
				  0,0,
 | 
			
		||||
				  0,10,
 | 
			
		||||
				  "Vertical",
 | 
			
		||||
				  1);
 | 
			
		||||
 | 
			
		||||
	dijkstra_path_new_to_list(nodes,
 | 
			
		||||
				  paths,
 | 
			
		||||
	dijkstra_path_new_to_list(solver,
 | 
			
		||||
				  0,5,
 | 
			
		||||
				  10,5,
 | 
			
		||||
				  "Horizontal",
 | 
			
		||||
@ -41,8 +38,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
	int opt;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	GList *nodes = NULL;
 | 
			
		||||
	GList *paths = NULL;
 | 
			
		||||
	struct dijkstra_solver *solver;
 | 
			
		||||
 | 
			
		||||
	GList *l = NULL;
 | 
			
		||||
	struct dijkstra_node *node;
 | 
			
		||||
@ -53,20 +49,20 @@ int main(int argc, char *argv[])
 | 
			
		||||
	// Process arguments
 | 
			
		||||
	while((opt = getopt(argc, argv, "vs")) != -1) {
 | 
			
		||||
		switch(opt)
 | 
			
		||||
				{
 | 
			
		||||
				case 'v':
 | 
			
		||||
					set_log_level(get_log_level() + 1);
 | 
			
		||||
					break;
 | 
			
		||||
				case 's':
 | 
			
		||||
					set_log_level(0);
 | 
			
		||||
					break;
 | 
			
		||||
				case ':':
 | 
			
		||||
				case '?':
 | 
			
		||||
					help(argv[0]);
 | 
			
		||||
					return 1;
 | 
			
		||||
				default:
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
		{
 | 
			
		||||
		case 'v':
 | 
			
		||||
			set_log_level(get_log_level() + 1);
 | 
			
		||||
			break;
 | 
			
		||||
		case 's':
 | 
			
		||||
			set_log_level(0);
 | 
			
		||||
			break;
 | 
			
		||||
		case ':':
 | 
			
		||||
		case '?':
 | 
			
		||||
			help(argv[0]);
 | 
			
		||||
			return 1;
 | 
			
		||||
		default:
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (optind == argc) {
 | 
			
		||||
@ -74,21 +70,27 @@ int main(int argc, char *argv[])
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	solver = dijkstra_solver_new();
 | 
			
		||||
	if (!solver) {
 | 
			
		||||
		report(LL_CRITICAL, "Memory allocation failure.");
 | 
			
		||||
		return 2;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Parse file list */
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
	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;
 | 
			
		||||
			printf("Node %p: %f,\t%f [%d paths]\n", node, node->position.x, node->position.y, g_list_length(node->paths));
 | 
			
		||||
		}
 | 
			
		||||
		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;
 | 
			
		||||
			printf("Path %p: %p (%f,%f) -> %p (%f,%f) \t\"%s\"\n", path,
 | 
			
		||||
			       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.",
 | 
			
		||||
	       g_list_length(nodes),
 | 
			
		||||
	       g_list_length(paths));
 | 
			
		||||
	       g_list_length(solver->nodes),
 | 
			
		||||
	       g_list_length(solver->paths));
 | 
			
		||||
 | 
			
		||||
	// Free memory
 | 
			
		||||
	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);
 | 
			
		||||
	dijkstra_solver_free(solver);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user