From: Karryanna Date: Thu, 9 Apr 2015 19:25:53 +0000 (+0200) Subject: Mix of changes O:) X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=2dda46b6d1cebc5205f7f98b4db4dcae40c11e55;p=leo.git Mix of changes O:) --- diff --git a/labeller.c b/labeller.c index f503154..46c6839 100644 --- a/labeller.c +++ b/labeller.c @@ -12,6 +12,7 @@ #define HASH_KEY_ATOMIC id #define HASH_WANT_FIND #define HASH_WANT_NEW +#define HASH_WANT_CLEANUP #include #include @@ -40,13 +41,13 @@ int conf_pop_size = 50; int conf_penalty_bound = 0; int conf_stagnation_bound = 0; -int conf_iteration_limit = 5; +int conf_iteration_limit = 4; int conf_term_cond = TERM_COND_ITERATIONS; int conf_breed_rbest_perc = 80; int conf_breed_pop_size_perc = 20; -int conf_breed_perc = 50; +int conf_breed_perc = 50; // Percentage of new pop created by breeding bool conf_mutate_children = 1; int conf_mutate_children_prob = 0.3; @@ -75,6 +76,7 @@ void labeller_init(void) { // mpool_requests = mp_new(BLOCK_SIZE); GARY_INIT(requests_point, 0); + GARY_INIT(requests_line, 0); GARY_INIT(requests_area, 0); GARY_INIT(buffer_line, 0); GARY_INIT(buffer_linelabel, 0); @@ -85,6 +87,8 @@ void make_bitmap_icon(struct point_variant *v, struct sym_icon *si) { v->width = si->sir.icon->width; v->height = si->sir.icon->height; + v->bitmap = malloc((int) ceil(v->width * v->height * sizeof(bool))); + for (int i=0; iwidth*v->height; i++) v->bitmap[i] = 1; } void make_bitmap_point(struct point_variant *v, struct sym_point *sp) @@ -111,10 +115,13 @@ void labeller_add_point(struct symbol *sym, struct osm_object *object, z_index_t */ struct request_point *r = GARY_PUSH(requests_point); + + r->request.type = REQUEST_POINT; + r->request.ind = num_requests++; + r->sym = sym; r->object = object; r->zindex = zindex; - ((struct request *)r)->ind = num_requests++; struct osm_node *n = (struct osm_node *) object; r->x = n->x; @@ -128,7 +135,6 @@ void labeller_add_point(struct symbol *sym, struct osm_object *object, z_index_t struct point_variant *v = GARY_PUSH(r->variants); - if (sym->type == SYMBOLIZER_ICON) switch (sym->type) { case SYMBOLIZER_ICON: @@ -142,8 +148,6 @@ void labeller_add_point(struct symbol *sym, struct osm_object *object, z_index_t // FIXME return; } - - sym_plan(sym, zindex); // TEMPORARY } void labeller_add_line(struct symbol *sym, z_index_t zindex) @@ -154,12 +158,28 @@ void labeller_add_line(struct symbol *sym, z_index_t zindex) sym_plan(sym, zindex); } +void labeller_add_linelabel(struct symbol *sym, struct osm_object *o, z_index_t zindex) +{ + struct buffer_linelabel *ll = GARY_PUSH(buffer_linelabel); + ll->way = (struct osm_way *) o; + ll->text = (struct sym_text *) sym; + ll->zindex = zindex; +} + void labeller_add_arealabel(struct symbol *sym UNUSED, struct osm_object *o, z_index_t zindex) { struct request_area *r = GARY_PUSH(requests_area); + + r->request.type = REQUEST_AREALABEL; + r->request.ind = num_requests++; + r->o = (struct osm_multipolygon *) o; r->zindex = zindex; - ((struct request *)r)->ind = num_requests++; + r->sym = (struct sym_text *) sym; + + GARY_INIT(r->text_variant, 0); + struct point_variant *v = GARY_PUSH(r->text_variant); + make_bitmap_label(v, r->sym); } void make_graph(void) @@ -171,43 +191,45 @@ void make_graph(void) for (uns i=0; is.o; - struct graph_node *prev = NULL; - struct osm_node *prev_node = NULL; + struct graph_node *g_prev = NULL; + struct osm_node *o_prev = NULL; + CLIST_FOR_EACH(struct osm_ref *, ref, way->nodes) { // FIXME: Shall osm_object's type be checked here? - struct osm_node *node = (struct osm_node *) ref->o; + struct osm_node *o_node = (struct osm_node *) ref->o; - struct graph_node *n = hash_find(ref->o->id); - if (!n) + struct graph_node *g_node = hash_find(ref->o->id); + if (!g_node) { - n = hash_new(ref->o->id); - GARY_INIT(n->edges, 0); + g_node = hash_new(ref->o->id); + GARY_INIT(g_node->edges, 0); + g_node->o = o_node; } - if (! prev) + if (! g_prev) { - prev = n; - prev_node = node; + g_prev = g_node; + o_prev = o_node; continue; } - struct graph_edge *e = (struct graph_edge *) mp_alloc(mp_edges, sizeof(struct graph_edge)); + struct graph_edge *e = mp_alloc(mp_edges, sizeof(struct graph_edge)); e->id = buffer_line[i].line->s.o->id; e->color = buffer_line[i].line->color; - e->length = hypot(abs(prev_node->x - node->x), abs(prev_node->y - node->y)); + e->length = hypot(abs(o_prev->x - o_node->x), abs(o_prev->y - o_node->y)); e->visited = 0; e->prev = NULL; e->next = NULL; - e->n1 = prev; - e->n2 = n; - e->longline = -1; + e->n1 = g_prev; + e->n2 = g_node; + e->longline = (uns) -1; e->text = NULL; e->sym = buffer_line[i].line; - struct graph_edge **edge = GARY_PUSH(prev->edges); + struct graph_edge **edge = GARY_PUSH(g_prev->edges); *edge = e; - edge = GARY_PUSH(n->edges); + edge = GARY_PUSH(g_node->edges); *edge = e; } } @@ -228,9 +250,10 @@ void label_graph(void) { for (uns j=0; jedges); j++) { - if (n->edges[j]->id == ((struct osm_object *) buffer_linelabel[i].way)->id) + if (n->edges[j]->id == buffer_linelabel[i].way->o.id) { n->edges[j]->text = buffer_linelabel[i].text; + n->edges[j]->zindex = buffer_linelabel[i].zindex; } } } @@ -262,7 +285,6 @@ void join_edge(struct graph_edge *e, int dir) *new = other_node->edges[i]; } - //if (1) // FIXME: same labels but not the same edge if ((!other->visited) && (e->text) && (other->text) && (e->text->text == other->text->text)) { if (e->color == other_node->edges[i]->color) @@ -307,14 +329,6 @@ void join_edge(struct graph_edge *e, int dir) } } -void labeller_add_linelabel(struct symbol *sym, struct osm_object *o, z_index_t zindex) -{ - struct buffer_linelabel *ll = GARY_PUSH(buffer_linelabel); - ll->way = (struct osm_way *) o; - ll->text = (struct sym_text *) sym; - ll->zindex = zindex; -} - void bfs(void) { GARY_INIT(bfs_queue, 0); @@ -326,13 +340,19 @@ void bfs(void) { struct graph_edge *e = node->edges[i]; - if (e->visited) HASH_CONTINUE; +// printf("Examining edge from [%.2f; %.2f] to [%.2f; %.2f]\n", +// e->n1->o->x, e->n1->o->y, e->n2->o->x, e->n2->o->y); + + // if (e->visited) HASH_CONTINUE; // FIXME: Is is correct? + if (e->visited) continue; +// printf("Continuing\n"); if (e->longline == (uns) -1) { GARY_PUSH(longlines); e->longline = num_longlines++; longlines[e->longline].first = e; } +// printf("Longline is %u\n", e->longline); e->visited = 1; @@ -353,26 +373,52 @@ void bfs(void) void make_segments(void) { - GARY_INIT(requests_line, 0); - for (uns i=0; itext) continue; +// printf("Survived! %s\n", osm_val_decode(longlines[i].first->text->text)); +printf("New longline\n"); struct request_line *request = GARY_PUSH(requests_line); + request->request.ind = -1; + request->request.type = REQUEST_LINELABEL; + GARY_INIT(request->segments, 0); + request->num_segments = 0; + + // ->num_variants FIXME + // ->variants FIXME + struct graph_edge *e = longlines[i].first; + if (! e) printf("Oops\n"); + num_requests++; while (e) { + if (! e->text) break; struct request_segment *r = GARY_PUSH(request->segments); request->num_segments++; - r->x1 = ((struct osm_node *) e->n1)->x; - r->y1 = ((struct osm_node *) e->n1)->y; - r->x2 = ((struct osm_node *) e->n2)->x; - r->y2 = ((struct osm_node *) e->n2)->y; - r->sym = e->sym; + + r->request.ind = num_requests++; + r->request.type = REQUEST_SEGMENT; + + struct osm_node *n = e->n1->o; + r->x1 = n->x; + r->y1 = n->y; + n = e->n2->o; + r->x2 = n->x; + r->y2 = n->y; r->k = abs(r->x2 - r->x1) / (abs(r->y2 - r->y1) + 0.001); // FIXME: Hack to prevent floating point exception when y2 = y1 + +printf("Segment [%.2f; %.2f] -- [%.2f; %.2f]\n", r->x1, r->y1, r->x2, r->y2); + + r->sym = e->sym; + r->zindex = e->zindex; + r->text = malloc(sizeof(struct sym_text)); + *(r->text) = *(e->text); + r->text->x = r->x1; + r->text->y = r->y1; + r->variant = malloc(sizeof(struct point_variant)); // FIXME - ((struct request *)r)->ind = num_requests++; make_bitmap_label(r->variant, e->text); e = e->next; @@ -387,45 +433,113 @@ void labeller_label(void) bfs(); make_segments(); +printf("Having %u point requests, %u line requests and %u area requests\n", GARY_SIZE(requests_point), GARY_SIZE(requests_line), GARY_SIZE(requests_area)); + + GARY_INIT(population1, conf_pop_size); + GARY_INIT(population2, conf_pop_size); make_population(); + printf("Dealing with %d requests\n", num_requests); + while (! shall_terminate()) { - // sort population by fitness - // alloc new population + iteration++; + + struct individual **swp = population1; + population1 = population2; + population2 = swp; + pop2_ind = 0; + } + + for (uns i=0; iplacements); i++) + { + switch (population1[0]->placements[i].request->type) + { + case REQUEST_POINT: ; + struct request_point *rp = (struct request_point *) population1[0]->placements[i].request; + switch (rp->sym->type) + { + case SYMBOLIZER_POINT: ; + struct sym_point *sp = (struct sym_point *) rp->sym; + sp->x = i*10; + sp->y = i*10; + sym_plan((struct symbol *) sp, rp->zindex); + break; + case SYMBOLIZER_ICON: ; + struct sym_icon *si = (struct sym_icon *) rp->sym; + si->sir.x = population1[0]->placements[i].x; + si->sir.y = population1[0]->placements[i].y; + sym_plan((struct symbol *) si, rp->zindex); + break; + default: + ; + } + break; + case REQUEST_AREALABEL: ; + struct request_area *ra = (struct request_area *) population1[0]->placements[i].request; + sym_plan((struct symbol *) ra->sym, ra->zindex); + break; + + case REQUEST_LINELABEL: ; + struct request_line *rl = (struct request_line *) population1[0]->placements[i].request; + for (uns j=0; jsegments); j++) + { + printf("Planning text %s to [%.2f; %.2f]\n", osm_val_decode(rl->segments[j].text->text), rl->segments[j].text->x, rl->segments[j].text->y); + rl->segments[j].text->next_duplicate = NULL; + rl->segments[j].text->next_in_tile = NULL; + sym_plan((struct symbol *) rl->segments[j].text, rl->segments[j].zindex); // FIXME: z-index + } + + } + } + + return; + + while (! shall_terminate()) + { + iteration++; + breed(); mutate(); elite(); rank_population(); + // sort population by fitness + + struct individual **swp = population1; + population1 = population2; + printf("Swapped populations\n"); + population2 = swp; + // GARY_RESIZE(population2, 0) -- is it needed? + pop2_ind = 0; } } void make_population(void) { - GARY_INIT(population1, 0); for (int i=0; imap, 0); - GARY_INIT(individual->placements, 0); + struct individual *individual = ep_alloc(ep_individuals); init_individual(individual); + population1[i] = individual; + int p = 0; for (uns j=0; jplacements); - init_placement(p, (struct request *) &requests_point[i]); + init_placement(&(individual->placements[p++]), (struct request *) &requests_point[j]); } for (uns j=0; jplacements); - init_placement(p, (struct request *) &requests_line[i]); + init_placement(&(individual->placements[p++]), (struct request *) &requests_line[j]); + for (uns k=0; kplacements[p++]), (struct request *) &requests_line[j].segments[k]); + } } for (uns j=0; jplacements); - init_placement(p, (struct request *) &requests_area[i]); + init_placement(&(individual->placements[p++]), (struct request *) &requests_area[j]); } + + ASSERT(p == num_requests); } } @@ -452,26 +566,31 @@ void breed(void) printf("%.2f\n", ((double) conf_breed_pop_size_perc/100)); int conf_breed_pop_size = ((double) conf_breed_pop_size_perc/100) * conf_pop_size; struct individual **breed_buffer; - while (i < conf_breed_rbest_perc * conf_pop_size) + while (i < conf_breed_pop_size) { + printf("%d < %d, breeding\n", i, conf_breed_pop_size); int parent1 = randint(1, conf_breed_pop_size); int parent2 = randint(1, conf_breed_pop_size); printf("Will breed %d and %d, chosen of %d best of %d population (intended to be %d)\n", parent1, parent2, conf_breed_pop_size, GARY_SIZE(population1), conf_pop_size); breed_buffer = perform_crossover(population1[parent1], population1[parent2]); - population2[2*i] = breed_buffer[0]; - population2[2*i+1] = breed_buffer[1]; + population2[pop2_ind++] = breed_buffer[0]; + population2[pop2_ind++] = breed_buffer[1]; free(breed_buffer); + i++; } acc += conf_breed_rbest_perc; + return; // FIXME: DEBUG HACK + int remaining = (1 - acc) * (conf_pop_size * conf_breed_perc); int step = remaining / conf_pop_size; for (; iplacements, 0); - GARY_INIT(child2->placements, 0); + struct individual *child1 = ep_alloc(ep_individuals); init_individual(child1); + struct individual *child2 = ep_alloc(ep_individuals); init_individual(child2); printf("Performing crossover\n"); for (uns i=0; iplacements); i++) { - printf("%dth placement\n", i); + printf("%dth placement out of %d\n", i, num_requests); if (! parent1->placements[i].processed) { - struct placement **clos_symbols; - GARY_INIT(clos_symbols, 0); - get_closure(clos_symbols, &(parent1->placements[i]), parent1, parent2); + struct placement **clos_symbols = get_closure(&(parent1->placements[i]), parent1, parent2); int x = randint(1, 2); if (x == 1) @@ -507,7 +622,7 @@ struct individual **perform_crossover(struct individual *parent1, struct individ copy_symbols(clos_symbols, parent2, child1); copy_symbols(clos_symbols, parent1, child2); } - printf("%lld\n", GARY_SIZE(clos_symbols)); + printf("Symbols copied; %lld\n", GARY_SIZE(clos_symbols)); GARY_FREE(clos_symbols); } @@ -530,8 +645,9 @@ void mutate(void) while (i < conf_mutate_rbest_perc * conf_pop_size) { int ind = randint(1, conf_mutate_pop_size); - population2[pop2_ind] = population1[ind]; + copy_individual(population2[pop2_ind], population1[ind]); perform_mutation(population2[pop2_ind]); + pop2_ind++; } } @@ -570,7 +686,7 @@ void elite(void) { for (int i=0; iplacements) * sizeof(bool)); chosen[placement->request->ind] = 1; @@ -642,15 +760,19 @@ void get_closure(struct placement **closure UNUSED, struct placement *placement GARY_FREE(overlapping); first++; } + + return closure; } void copy_symbols(struct placement **closure, struct individual *parent, struct individual *child) { - printf("%.2f\n", child->penalty); + //printf("%d\n", child->penalty); + //printf("Closure size: %lld\n", GARY_SIZE(closure)); for (uns i=0; irequest->ind; child->placements[ind] = parent->placements[ind]; + child->placements[ind].processed = 0; } } @@ -676,11 +798,20 @@ void init_placement(struct placement *p, struct request *r) p->processed = 0; } +void init_individual(struct individual *i) +{ +//printf("Initing individual\n"); + GARY_INIT(i->placements, num_requests); + GARY_INIT(i->map, 0); + i->penalty = 0; // FIXME +} + struct placement **get_overlapping(struct placement *p UNUSED) { struct placement **buffer; GARY_INIT(buffer, 0); -return buffer; } + return buffer; +} void filter(struct placement **list UNUSED, bool *pred UNUSED) { @@ -697,3 +828,21 @@ double randdouble(void) // FIXME: How the hell shall double in range <0, 1> be generated? O:) return 0.5; } + +void cleanup(void) +{ + hash_cleanup(); + GARY_FREE(requests_point); + GARY_FREE(requests_line); + GARY_FREE(requests_area); +} + +void copy_individual(struct individual *src, struct individual *dest) +{ + src->penalty = dest->penalty; + GARY_INIT(dest->placements, GARY_SIZE(src->placements)); + for (uns i=0; iplacements); i++) + { + dest->placements[i] = src->placements[i]; + } +} diff --git a/labeller.h b/labeller.h index fae5f21..8f1b0fa 100644 --- a/labeller.h +++ b/labeller.h @@ -11,6 +11,9 @@ enum label_type enum request_type { REQUEST_POINT, + REQUEST_AREALABEL, + REQUEST_LINELABEL, + REQUEST_SEGMENT, }; enum term_cond @@ -50,7 +53,7 @@ struct request_point { struct request request; struct symbol *sym; - struct osm_object *object; + struct osm_object *object; // FIXME: Linked also by sym z_index_t zindex; double x; double y; @@ -70,6 +73,8 @@ struct request_segment double k; struct sym_line *sym; struct point_variant *variant; + struct sym_text *text; + z_index_t zindex; }; struct request_line @@ -86,6 +91,8 @@ struct request_area { struct request request; struct osm_multipolygon *o; + struct sym_text *sym; + struct point_variant *text_variant; z_index_t zindex; }; @@ -105,6 +112,7 @@ struct buffer_linelabel struct graph_node { osm_id_t id; + struct osm_node *o; struct graph_edge **edges; }; @@ -121,6 +129,7 @@ struct graph_edge uns longline; struct sym_text *text; struct sym_line *sym; + z_index_t zindex; }; struct longline @@ -177,13 +186,14 @@ struct individual **perform_crossover(struct individual *parent1, struct individ void perform_mutation(struct individual *individual); void init_placement(struct placement *p, struct request *r); +void init_individual(struct individual *i); void gen_coords_point(struct placement *p); void gen_coords(struct placement *p); struct map_part **get_parts(struct placement *symbol, struct individual *individual); int randint(int min, int max); -void get_closure(struct placement **closure, struct placement *placement, struct individual *parent1, struct individual *parent2); +struct placement **get_closure(struct placement *placement, struct individual *parent1, struct individual *parent2); void copy_symbols(struct placement **closure, struct individual *parent, struct individual *child); void move_symbol(struct placement *p); void move_symbol_point(struct placement *p); @@ -194,4 +204,8 @@ void filter(struct placement **list, bool *pred); int flip(int a, int b); double randdouble(void); +void cleanup(void); + +void copy_individual(struct individual *src, struct individual *dest); + #endif diff --git a/sym-point.c b/sym-point.c index 3de1264..b3cb911 100644 --- a/sym-point.c +++ b/sym-point.c @@ -31,8 +31,8 @@ static void sym_point_draw(struct symbol *sym, struct svg *svg) { case VALUE_CIRCLE: svg_push_element(svg, "circle"); - svg_set_attr_dimen(svg, "cx", n->x); - svg_set_attr_dimen(svg, "cy", n->y); + svg_set_attr_dimen(svg, "cx", p->x); + svg_set_attr_dimen(svg, "cy", p->y); // svg_set_attr_dimen(svg, "r", p->size / 2); // DEBUG HACK svg_set_attr_dimen(svg, "r", 3); break; @@ -143,7 +143,7 @@ static void sym_icon_gen(struct osm_object *o, struct style_info *si, struct svg // style_get_number(si, PROP_ICON_OPACITY, &sir->opacity); labeller_add_point(&sic->s, o, sym_zindex(o, si, 4)); - // sym_plan(&sic->s, sym_zindex(o, si, 4)); + //sym_plan(&sic->s, sym_zindex(o, si, 4)); } struct symbolizer symbolizer_icon = { diff --git a/sym-text.c b/sym-text.c index 66e834a..f2f901e 100644 --- a/sym-text.c +++ b/sym-text.c @@ -442,7 +442,7 @@ static void sym_text_node(struct osm_object *o, struct style_info *si, osm_val_t return; } - sym_plan(&st->s, sym_zindex(o, si, 5)); + //sym_plan(&st->s, sym_zindex(o, si, 5)); } static void sym_text_center(struct osm_object *o, struct style_info *si, osm_val_t text, double x, double y) @@ -459,11 +459,12 @@ static void sym_text_center(struct osm_object *o, struct style_info *si, osm_val text_fix_placement(st); if (o->type == OSM_TYPE_WAY && !osm_way_cyclic_p((struct osm_way *) o)) { + //sym_plan(&st->s, sym_zindex(o, si, 4.9)); labeller_add_linelabel(&st->s, o, sym_zindex(o, si, 4.9)); } else { -// sym_plan(&st->s, sym_zindex(o, si, 4.9)); + //sym_plan(&st->s, sym_zindex(o, si, 4.9)); labeller_add_arealabel(&st->s, o, sym_zindex(o, si, 4.9)); } } diff --git a/sym.h b/sym.h index e846a79..6af4f2b 100644 --- a/sym.h +++ b/sym.h @@ -71,6 +71,8 @@ struct sym_point { double fill_opacity; bool do_stroke; bool do_fill; + double x; + double y; }; // FIXME: Make sym_*_new() and symbolizer structs internal