2 * Hic Est Leo -- Graph and Routing
4 * (c) 2022 Martin Mares <mj@ucw.cz>
8 #include <ucw/clists.h>
9 #include <ucw/mempool.h>
19 static struct mempool *graph_pool;
20 static clist graph_vertices;
24 struct osm_node *node;
29 cnode n; // In src->edges
30 struct graph_vertex *dest;
31 struct graph_edge *twin;
36 static uint num_vertices;
37 static uint num_edges;
39 static struct graph_vertex *graph_lookup_vertex(struct osm_node *n)
43 struct graph_vertex *v = mp_alloc_zero(graph_pool, sizeof(*v));
46 clist_init(&v->edges);
47 clist_add_tail(&graph_vertices, &v->n);
53 static struct graph_edge *graph_add_edge(struct graph_vertex *u, struct graph_vertex *v, struct osm_way *way, double length)
55 struct graph_edge *e1 = mp_alloc_zero(graph_pool, sizeof(*e1));
56 struct graph_edge *e2 = mp_alloc_zero(graph_pool, sizeof(*e2));
59 clist_add_tail(&u->edges, &e1->n);
65 clist_add_tail(&v->edges, &e2->n);
74 static void graph_optimize(void)
76 struct graph_vertex *v, *tmp;
78 CLIST_WALK_DELSAFE(v, graph_vertices, tmp)
81 CLIST_FOR_EACH(struct graph_edge *, e, v->edges)
86 struct graph_edge *e1 = clist_remove_head(&v->edges);
87 struct graph_edge *f1 = clist_remove_head(&v->edges);
88 struct graph_vertex *x = e1->dest;
89 struct graph_vertex *y = f1->dest;
90 clist_remove(&e1->twin->n);
91 clist_remove(&f1->twin->n);
97 graph_add_edge(x, y, e1->way, e1->length + f1->length);
102 static bool way_is_edge(struct osm_way *w)
104 osm_val_t hwy = osm_obj_find_tag(&w->o, KEY_HIGHWAY);
109 case VALUE_SECONDARY:
110 case VALUE_MOTORWAY_LINK:
111 case VALUE_TRUNK_LINK:
112 case VALUE_PRIMARY_LINK:
113 case VALUE_SECONDARY_LINK:
120 static void way_add_edge(struct osm_way *w)
122 struct osm_node *prev_n = NULL;
123 struct graph_vertex *prev_v = NULL;
125 OSM_FOR_EACH_BEGIN(struct osm_node *, n, w->nodes)
127 struct graph_vertex *v = graph_lookup_vertex(n);
130 double length = hypot(n->x - prev_n->x, n->y - prev_n->y);
131 graph_add_edge(prev_v, v, w, length);
139 void graph_build(void)
141 graph_pool = mp_new(65536);
142 clist_init(&graph_vertices);
144 CLIST_FOR_EACH(struct data_source *, ds, map_sources)
145 CLIST_FOR_EACH(struct osm_way *, w, ds->osm->obj_list[OSM_TYPE_WAY])
150 msg(L_INFO, "Built road graph: %u vertices, %u edges", num_vertices, num_edges);
153 msg(L_INFO, "Optimized road graph: %u vertices, %u edges", num_vertices, num_edges);