]> mj.ucw.cz Git - leo.git/commitdiff
Labelling: A bit of work done
authorKarryanna <karry@karryanna.cz>
Tue, 7 Apr 2015 13:32:50 +0000 (15:32 +0200)
committerKarryanna <karry@karryanna.cz>
Tue, 7 Apr 2015 13:32:50 +0000 (15:32 +0200)
while much more remains…

Makefile
labeller.c [new file with mode: 0644]
labeller.h [new file with mode: 0644]
leo.c
poskole.css
sym-line.c
sym-point.c
sym-text.c

index 036bcda70d56be1850bac53145d49937501b5ad5..0146664d7372ef4a68aed8cff34d334d59392636 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ include $(BUILDSYS)/Maketop
 PROGS+=$(o)/leo
 CFLAGS+=$(LIBUCW_CFLAGS)
 
-LEO_MODULES=leo xml osm svg svg-icon css-parse css-lex style css dict sym sym-point sym-line sym-text map shp fixed
+LEO_MODULES=leo xml osm svg svg-icon css-parse css-lex style css dict sym sym-point sym-line sym-text map shp fixed labeller
 LEO_OBJECTS=$(addprefix $(o)/, $(addsuffix .o, $(LEO_MODULES)))
 $(o)/leo: $(LEO_OBJECTS)
 
diff --git a/labeller.c b/labeller.c
new file mode 100644 (file)
index 0000000..7f74bbf
--- /dev/null
@@ -0,0 +1,678 @@
+#include <ucw/lib.h>
+#include <ucw/gary.h>
+#include <ucw/mempool.h>
+#include <ucw/eltpool.h>
+
+#include "leo.h"
+#include "sym.h"
+#include "labeller.h"
+
+#define HASH_NODE struct graph_node
+#define HASH_PREFIX(x) hash_##x
+#define HASH_KEY_ATOMIC id
+#define HASH_WANT_FIND
+#define HASH_WANT_NEW
+#include <ucw/hashtable.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#define BLOCK_SIZE 4096
+
+//struct mempool *mpool_requests;
+
+static struct request_point *requests_point;
+static struct request_line *requests_line;
+static struct request_area *requests_area;
+
+static struct graph_edge *bfs_queue;
+static struct longline *longlines; int num_longlines;
+static struct buffer_line *buffer_line;
+static struct buffer_linelabel *buffer_linelabel;
+
+struct eltpool *ep_individuals;
+
+struct individual **population1;
+struct individual **population2;
+
+int conf_pop_size = 50;
+
+int conf_penalty_bound = 0;
+int conf_stagnation_bound = 0;
+int conf_iteration_limit = 5;
+
+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;
+
+bool conf_mutate_children = 1;
+int conf_mutate_children_prob = 0.3;
+
+int conf_mutate_rbest_perc = 60;
+int conf_mutate_pop_size_perc = 20;
+
+int conf_mutate_move_bound = 0.2;
+int conf_mutate_regen_bound = 0.1;
+int conf_mutate_chvar_bound = 0.1;
+
+int conf_elite_perc = 5;
+
+int old_best = 0; // FIXME: Shall be int max
+int iteration = 0;
+int pop2_ind;
+
+int conf_part_size = 50;
+
+int move_min = 0;
+int move_max = 1;
+
+void labeller_init(void)
+{
+//  mpool_requests = mp_new(BLOCK_SIZE);
+  GARY_INIT(requests_point, 0);
+  GARY_INIT(requests_area, 0);
+  GARY_INIT(buffer_line, 0);
+  GARY_INIT(buffer_linelabel, 0);
+  ep_individuals = ep_new(sizeof(struct individual), 1);
+}
+
+void make_bitmap_icon(struct point_variant *v, struct sym_icon *si)
+{
+  v->width = si->sir.icon->width;
+  v->height = si->sir.icon->height;
+}
+
+void make_bitmap_point(struct point_variant *v, struct sym_point *sp)
+{
+  v->width = v->height = sp->size;
+  v->bitmap = malloc(sp->size*sp->size * sizeof(bool));
+  // FIXME: Okay, memset would be much nicer here
+  for (int i=0; i<sp->size*sp->size; i++) v->bitmap[i] = 1;
+}
+
+void make_bitmap_label(struct point_variant *v UNUSED, struct sym_text *text UNUSED)
+{
+}
+
+void labeller_add_point(struct symbol *sym, struct osm_object *object, z_index_t zindex)
+{
+/* FIXME
+   What does correct check look like?
+  if (object->type != OSM_TYPE_NODE)
+  {
+    // FIXME
+    return;
+  }
+*/
+
+  struct request_point *r = GARY_PUSH(requests_point);
+  r->sym = sym;
+  r->object = object;
+  r->zindex = zindex;
+
+  struct osm_node *n = (struct osm_node *) object;
+  r->x = n->x;
+  r->y = n->y;
+
+  r->offset_x = 0;
+  r->offset_y = 0;
+
+  r->num_variants = 1;
+  GARY_INIT(r->variants, 0);
+
+  struct point_variant *v = GARY_PUSH(r->variants);
+
+  if (sym->type == SYMBOLIZER_ICON)
+  switch (sym->type)
+  {
+    case SYMBOLIZER_ICON:
+      make_bitmap_icon(v, (struct sym_icon *) sym);
+      break;
+    case SYMBOLIZER_POINT:
+      make_bitmap_point(v, (struct sym_point *) sym);
+      break;
+    default:
+      // Oops :)
+      // FIXME
+      return;
+  }
+
+  sym_plan(sym, zindex); // TEMPORARY
+}
+
+void labeller_add_line(struct symbol *sym, z_index_t zindex)
+{
+  struct buffer_line *b = GARY_PUSH(buffer_line);
+  b->line = (struct sym_line *) sym;
+  b->zindex = zindex;
+  sym_plan(sym, 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->o = (struct osm_multipolygon *) o;
+  r->zindex = zindex;
+}
+
+void make_graph(void)
+{
+  hash_init();
+  struct mempool *mp_edges = mp_new(BLOCK_SIZE);
+
+  printf("Extracting nodes, will iterate over %lld ways\n", GARY_SIZE(buffer_line));
+  for (uns i=0; i<GARY_SIZE(buffer_line); i++)
+  {
+    struct osm_way *way = (struct osm_way *) buffer_line[i].line->s.o;
+    struct graph_node *prev = NULL;
+    struct osm_node *prev_node = 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 graph_node *n = hash_find(ref->o->id);
+      if (!n)
+      {
+        n = hash_new(ref->o->id);
+        GARY_INIT(n->edges, 0);
+      }
+
+      if (! prev)
+      {
+        prev = n;
+        prev_node = node;
+        continue;
+      }
+
+      struct graph_edge *e = (struct graph_edge *) 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->visited = 0;
+      e->prev = NULL;
+      e->next = NULL;
+      e->n1 = prev;
+      e->n2 = n;
+      e->longline = -1;
+      e->text = NULL;
+      e->sym = buffer_line[i].line;
+
+      struct graph_edge **edge = GARY_PUSH(prev->edges);
+      *edge = e;
+      edge = GARY_PUSH(n->edges);
+      *edge = e;
+    }
+  }
+}
+
+void label_graph(void)
+{
+  for (uns i=0; i<GARY_SIZE(buffer_linelabel); i++)
+  {
+    CLIST_FOR_EACH(struct osm_ref *, ref, buffer_linelabel[i].way->nodes)
+    {
+      struct graph_node *n = hash_find(ref->o->id);
+      if (n == NULL)
+      {
+        // FIXME: What shall be done?
+      }
+      else
+      {
+        for (uns j=0; j<GARY_SIZE(n->edges); j++)
+        {
+          if (n->edges[j]->id == ((struct osm_object *) buffer_linelabel[i].way)->id)
+          {
+            n->edges[j]->text = buffer_linelabel[i].text;
+          }
+        }
+      }
+    }
+  }
+}
+
+void join_edge(struct graph_edge *e, int dir)
+{
+  struct graph_node *other_node = NULL;
+  switch (dir)
+  {
+    case 1:
+      other_node = e->n2;
+      break;
+    case 2:
+      other_node = e->n1;
+      break;
+    // FIXME: default?
+  }
+
+  struct graph_edge *candidate = NULL;
+  for (uns i=0; i<GARY_SIZE(other_node->edges); i++)
+  {
+    struct graph_edge *other = other_node->edges[i];
+    if (! other->visited)
+    {
+    printf("Trying to add %dth edge\n", GARY_SIZE(bfs_queue)+1);
+    struct graph_edge **new = GARY_PUSH(bfs_queue);
+    *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)
+      {
+        if ((!candidate) || (candidate->length < other->length))
+        {
+          candidate = other;
+        }
+      }
+      else
+      {
+        // Beware: Name conflict here
+      }
+    }
+  }
+
+  if (candidate)
+  {
+    candidate->longline = e->longline;
+    if (dir == 1)
+    {
+      if (candidate->n2 != e->n1)
+      {
+       candidate->n1 = candidate->n2;
+       candidate->n2 = e->n1;
+      }
+      e->prev = candidate;
+      candidate->next = e;
+
+      longlines[e->longline].first = candidate;
+    }
+    else
+    {
+      if (candidate->n1 != e->n2)
+      {
+       candidate->n2 = candidate->n1;
+       candidate->n1 = e->n2;
+      }
+      e->next = candidate;
+      candidate->prev = e;
+    }
+  }
+}
+
+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);
+  GARY_INIT(longlines, 0);
+
+  HASH_FOR_ALL(hash, node)
+  {
+    for (uns i=0; i<GARY_SIZE(node->edges); i++)
+    {
+      struct graph_edge *e = node->edges[i];
+
+      if (e->visited) HASH_CONTINUE;
+      if (e->longline == (uns) -1)
+      {
+        GARY_PUSH(longlines);
+        e->longline = num_longlines++;
+        longlines[num_longlines].first = e;
+      }
+
+      e->visited = 1;
+
+      if (! e->prev)
+      {
+        join_edge(e, 1);
+      }
+      if (! e->next)
+      {
+        join_edge(e, 2);
+      }
+    }
+  }
+  HASH_END_FOR;
+
+  GARY_FREE(bfs_queue);
+}
+
+void make_segments(void)
+{
+  GARY_INIT(requests_line, 0);
+
+  for (uns i=0; i<GARY_SIZE(longlines); i++)
+  {
+    struct request_line *request = GARY_PUSH(requests_line);
+    GARY_INIT(request->segments, 0);
+    struct graph_edge *e = longlines[i].first;
+    while (e)
+    {
+      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->k = abs(r->x2 - r->x1) / abs(r->y2 - r->y1);
+      r->variant = malloc(sizeof(struct point_variant)); // FIXME
+      make_bitmap_label(r->variant, e->text);
+
+      e = e->next;
+    }
+  }
+}
+
+void labeller_label(void)
+{
+  make_graph();
+  label_graph();
+  bfs();
+  make_segments();
+
+  make_population();
+
+  while (! shall_terminate())
+  {
+    // sort population by fitness
+    // alloc new population
+    breed();
+    mutate();
+    elite();
+    rank_population();
+  }
+}
+
+void make_population(void)
+{
+  GARY_INIT(population1, 0);
+  for (int i=0; i<conf_pop_size; i++)
+  {
+    struct individual *individual = ep_alloc(ep_individuals);
+    struct individual **ind = GARY_PUSH(population1);
+    *ind = individual;
+    GARY_INIT(individual->map, 0);
+    GARY_INIT(individual->placements, 0);
+
+    for (uns j=0; j<GARY_SIZE(requests_point); j++)
+    {
+      struct placement *p = GARY_PUSH(individual->placements);
+      init_placement(p, (struct request *) &requests_point[i]);
+    }
+    for (uns j=0; j<GARY_SIZE(requests_line); j++)
+    {
+      struct placement *p = GARY_PUSH(individual->placements);
+      init_placement(p, (struct request *) &requests_line[i]);
+    }
+    for (uns j=0; j<GARY_SIZE(requests_area); j++)
+    {
+      struct placement *p = GARY_PUSH(individual->placements);
+      init_placement(p, (struct request *) &requests_area[i]);
+    }
+  }
+}
+
+bool shall_terminate(void)
+{
+  switch (conf_term_cond)
+  {
+    case TERM_COND_PENALTY:
+      return (population1[0]->penalty < conf_penalty_bound);
+    case TERM_COND_STAGNATION:
+      return (abs(old_best - population1[0]->penalty) < conf_stagnation_bound);
+    case TERM_COND_ITERATIONS:
+      return (iteration >= conf_iteration_limit);
+    default:
+      // FIXME: Warn the user that no condition is set
+      return 1;
+  }
+}
+
+void breed(void)
+{
+  int acc = 0;
+  int i=0;
+  int conf_breed_pop_size = conf_breed_pop_size_perc * conf_pop_size;
+  struct individual **breed_buffer;
+  while (i < conf_breed_rbest_perc * conf_pop_size)
+  {
+    int parent1 = randint(1, conf_breed_pop_size);
+    int parent2 = randint(1, conf_breed_pop_size);
+    breed_buffer = perform_crossover(population1[parent1], population1[parent2]);
+    population2[2*i] = breed_buffer[0];
+    population2[2*i+1] = breed_buffer[1];
+    free(breed_buffer);
+  }
+
+  acc += conf_breed_rbest_perc;
+
+  int remaining = (1 - acc) * (conf_pop_size * conf_breed_perc);
+  int step = remaining / conf_pop_size;
+  for (; i<conf_pop_size; i += 2)
+  {
+    breed_buffer = perform_crossover(population1[i*step], population1[i*(step+1)]);
+    population2[2*i] = breed_buffer[0];
+    population2[2*i+1] = breed_buffer[1];
+  }
+
+  // FIXME: Could there be one missing individual?
+}
+
+struct individual **perform_crossover(struct individual *parent1, struct individual *parent2)
+{
+  struct individual **buffer = malloc(2*sizeof(struct individual));
+  struct individual *child1 = ep_alloc(ep_individuals);
+  struct individual *child2 = ep_alloc(ep_individuals);
+
+  for (uns i=0; i<GARY_SIZE(parent1->placements); i++)
+  {
+    if (! parent1->placements[i].processed)
+    {
+      struct placement **clos_symbols;
+      GARY_INIT(clos_symbols, 0);
+      get_closure(clos_symbols, &(parent1->placements[i]), parent1, parent2);
+      int x = randint(1, 2);
+
+      if (x == 1)
+      {
+        copy_symbols(clos_symbols, parent1, child1);
+        copy_symbols(clos_symbols, parent2, child2);
+      }
+      else
+      {
+        copy_symbols(clos_symbols, parent2, child1);
+        copy_symbols(clos_symbols, parent1, child2);
+      }
+      GARY_FREE(clos_symbols);
+    }
+
+    if (conf_mutate_children)
+    {
+      if (randint(1, 1000) < conf_mutate_children_prob * 1000) perform_mutation(child1);
+      if (randint(1, 1000) < conf_mutate_children_prob * 1000) perform_mutation(child2);
+    }
+  }
+
+  buffer[0] = child1;
+  buffer[1] = child2;
+  return buffer;
+}
+
+void mutate(void)
+{
+  int i = 0;
+  int conf_mutate_pop_size = conf_mutate_pop_size_perc * conf_pop_size;
+  while (i < conf_mutate_rbest_perc * conf_pop_size)
+  {
+    int ind = randint(1, conf_mutate_pop_size);
+    population2[pop2_ind] = population1[ind];
+    perform_mutation(population2[pop2_ind]);
+  }
+}
+
+void perform_mutation(struct individual *individual)
+{
+  for (uns i=0; i<GARY_SIZE(individual->placements); i++)
+  {
+    int x = randint(1, 1000);
+    int acc = 0;
+
+    if (x <= acc + conf_mutate_move_bound)
+    {
+      move_symbol(&(individual->placements[i]));
+      continue;
+    }
+    acc += conf_mutate_move_bound;
+
+    if (x <= acc + conf_mutate_regen_bound)
+    {
+      gen_coords(&(individual->placements[i]));
+      continue;
+    }
+    acc += conf_mutate_regen_bound;
+
+    if (x <= acc + conf_mutate_chvar_bound)
+    {
+      if (0) // if num_variants > 1
+      {
+        // FIXME: assign new variant
+      }
+    }
+  }
+}
+
+void elite(void)
+{
+  for (int i=0; i<conf_elite_perc * conf_pop_size; i++)
+  {
+    population2[pop2_ind] = population1[0];
+  }
+}
+
+void rank_population(void)
+{
+  // FIXME
+}
+
+void gen_coords(struct placement *p)
+{
+  switch(p->request->type)
+  {
+    case REQUEST_POINT:
+      gen_coords_point(p);
+  }
+}
+
+void gen_coords_point(struct placement *p UNUSED)
+{
+  // FIXME
+}
+
+struct map_part **get_parts(struct placement *symbol, struct individual *individual)
+{
+  struct map_part **buffer;
+  GARY_INIT(buffer, 0);
+  int x_min = symbol->x / conf_part_size;
+  int x_max = (symbol->x /*+ symbol->bitmap->width*/ + conf_part_size - 1) / conf_part_size;
+  int y_min = symbol->y / conf_part_size;
+  int y_max = (symbol->y /*+ symbol->bitmap->height*/ + conf_part_size - 1) / conf_part_size;
+
+  for (int x=x_min; x < x_max; x++)
+    for (int y=y_min; y < y_max; y++)
+    {
+      struct map_part *m = GARY_PUSH(buffer);
+      *m = individual->map[x][y];
+    }
+
+  return buffer;
+}
+
+int randint(int min, int max)
+{
+  int r = random();
+  return (r * (max - min));
+}
+
+void get_closure(struct placement **closure UNUSED, struct placement *placement UNUSED, struct individual *parent1 UNUSED, struct individual *parent2 UNUSED)
+{
+  bool *chosen = malloc(GARY_SIZE(parent1->placements) * sizeof(bool));
+  chosen[placement->request->ind] = 1;
+
+  struct placement **p = GARY_PUSH(closure); *p = placement;
+
+  uns first = 0;
+  while (first < GARY_SIZE(closure))
+  {
+    struct placement **overlapping = get_overlapping(placement);
+    filter(overlapping, chosen);
+    for (uns j=0; j<GARY_SIZE(overlapping); j++)
+    {
+      p = GARY_PUSH(closure); *p = overlapping[j];
+      chosen[overlapping[j]->request->ind] = 1;
+    }
+    GARY_FREE(overlapping);
+  }
+}
+
+void copy_symbols(struct placement **closure, struct individual *parent, struct individual *child)
+{
+  for (uns i=0; i<GARY_SIZE(closure); i++)
+  {
+    int ind = closure[i]->request->ind;
+    child->placements[ind] = parent->placements[ind];
+  }
+}
+
+void move_symbol(struct placement *p)
+{
+  switch (p->request->type)
+  {
+    case REQUEST_POINT:
+      move_symbol_point(p);
+  }
+}
+
+void move_symbol_point(struct placement *p)
+{
+  p->x += (double) (move_min + randdouble()) * flip(1, -1);
+  p->y += (double) (move_min + randdouble()) * flip(1, -1);
+}
+
+void init_placement(struct placement *p UNUSED, struct request *r UNUSED)
+{
+  // FIXME
+}
+
+struct placement **get_overlapping(struct placement *p UNUSED)
+{
+  struct placement **buffer;
+  GARY_INIT(buffer, 0);
+return buffer; }
+
+void filter(struct placement **list UNUSED, bool *pred UNUSED)
+{
+  // FIXME
+}
+
+int flip(int a, int b)
+{
+  return (random() % 2 ? a : b);
+}
+
+double randdouble(void)
+{
+  // FIXME: How the hell shall double in range <0, 1> be generated? O:)
+  return 0.5;
+}
diff --git a/labeller.h b/labeller.h
new file mode 100644 (file)
index 0000000..fae5f21
--- /dev/null
@@ -0,0 +1,197 @@
+#ifndef _LEO_LABELLER_H
+#define _LEO_LABELLER_H
+
+enum label_type
+{
+  LABEL_POINT,
+  LABEL_LINE,
+  LABEL_AREA,
+};
+
+enum request_type
+{
+  REQUEST_POINT,
+};
+
+enum term_cond
+{
+  TERM_COND_PENALTY,
+  TERM_COND_STAGNATION,
+  TERM_COND_ITERATIONS,
+};
+
+struct sym_placement
+{
+  double x;
+  double y;
+  int variant;
+  struct request *request;
+};
+
+struct request
+{
+  enum request_type type;
+  int ind;
+};
+
+struct point_variant
+{
+  double width;
+  double height;
+  bool *bitmap;
+};
+
+struct line_variant
+{
+  bool *masks;
+};
+
+struct request_point
+{
+  struct request request;
+  struct symbol *sym;
+  struct osm_object *object;
+  z_index_t zindex;
+  double x;
+  double y;
+  double offset_x;
+  double offset_y;
+  int num_variants;
+  struct point_variant *variants;
+};
+
+struct request_segment
+{
+  struct request request;
+  double x1;
+  double y1;
+  double x2;
+  double y2;
+  double k;
+  struct sym_line *sym;
+  struct point_variant *variant;
+};
+
+struct request_line
+{
+  struct request request;
+  struct symbol *sym;
+  int num_variants;
+  int num_segments;
+  struct line_variant *variants;
+  struct request_segment *segments;
+};
+
+struct request_area
+{
+  struct request request;
+  struct osm_multipolygon *o;
+  z_index_t zindex;
+};
+
+struct buffer_line
+{
+  struct sym_line *line;
+  z_index_t zindex;
+};
+
+struct buffer_linelabel
+{
+  struct osm_way *way;
+  struct sym_text *text;
+  z_index_t zindex;
+};
+
+struct graph_node
+{
+  osm_id_t id;
+  struct graph_edge **edges;
+};
+
+struct graph_edge
+{
+  osm_id_t id;
+  double length;
+  color_t color;
+  bool visited;
+  struct graph_edge *prev;
+  struct graph_edge *next;
+  struct graph_node *n1;
+  struct graph_node *n2;
+  uns longline;
+  struct sym_text *text;
+  struct sym_line *sym;
+};
+
+struct longline
+{
+  uns id;
+  struct graph_edge *first;
+};
+
+struct placement
+{
+  double x;
+  double y;
+  int variant_used;
+  bool processed;
+  struct request *request;
+};
+
+struct map_part
+{
+};
+
+struct individual
+{
+  struct placement *placements;
+  struct map_part **map;
+  int penalty;
+};
+
+void labeller_init(void);
+void labeller_add_point(struct symbol *sym, struct osm_object *object, z_index_t zindex);
+void labeller_add_line(struct symbol *sym, z_index_t zindex);
+void labeller_label(void);
+void labeller_add_linelabel(struct symbol *sym, struct osm_object *o, z_index_t zindex);
+void labeller_add_arealabel(struct symbol *sym, struct osm_object *o, z_index_t zindex);
+
+void make_bitmap_icon(struct point_variant *v, struct sym_icon *si);
+void make_bitmap_point(struct point_variant *v, struct sym_point *sp);
+void make_bitmap_label(struct point_variant *v, struct sym_text *text);
+
+void make_graph(void);
+void label_graph(void);
+void join_edge(struct graph_edge *e, int dir);
+void bfs(void);
+void make_segments(void);
+
+void make_population(void);
+bool shall_terminate(void);
+void breed(void);
+void mutate(void);
+void elite(void);
+void rank_population(void);
+
+struct individual **perform_crossover(struct individual *parent1, struct individual *parent2);
+void perform_mutation(struct individual *individual);
+
+void init_placement(struct placement *p, struct request *r);
+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);
+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);
+
+struct placement **get_overlapping(struct placement *p);
+void filter(struct placement **list, bool *pred);
+
+int flip(int a, int b);
+double randdouble(void);
+
+#endif
diff --git a/leo.c b/leo.c
index 5d02f680a90c6e84fe69954e5e32bbf73a2df4d7..75df2e7a4f3b85b4e24ee476da3f1116fd5c5ae1 100644 (file)
--- a/leo.c
+++ b/leo.c
@@ -18,6 +18,8 @@
 #include "sym.h"
 #include "map.h"
 
+#include "labeller.h"
+
 uns debug_dump_source, debug_dump_after_proj, debug_dump_after_scaling;
 uns debug_dump_multipolygons, debug_dump_css, debug_dump_styling, debug_dump_symbols;
 
@@ -113,8 +115,11 @@ static void draw_scale(struct svg *svg)
 int main(int argc UNUSED, char **argv)
 {
   cf_def_file = "map.cf";
+// HACKING
+  cf_def_file = argv[1];
   cf_declare_section("Debug", &debug_cf, 0);
-  opt_parse(&options, argv+1);
+  opt_parse(&options, argv+2);
+// TILL HERE
 
   osm_init();
   styles_init();
@@ -135,6 +140,7 @@ int main(int argc UNUSED, char **argv)
     }
 
   sym_init();
+  labeller_init();
 
   map_apply_styles(svg);
 
@@ -165,6 +171,7 @@ int main(int argc UNUSED, char **argv)
   struct svg_icon *logo = svg_icon_load(svg, "../logo/kocka-s-okrajem.svg");
 #endif
 
+  labeller_label();
   sym_draw_all(svg);
 
   // Draw logo
index 30631f5ae39eff668a51fbc5984c1bc4e9d1a105..96007f313c37ca8511c5e181cc1c71c9088f66b0 100644 (file)
@@ -5,6 +5,30 @@ way::* {
        linecap: round;
        casing-linejoin: round;
        casing-linecap: round;
+
+
+
+       text: name;
+       text-halo-radius: 0.5;
+       text-color: #000000;
+       text-halo-color: #ffffff;
+       text-halo-opacity: 0.8;
+       text-position: center;
+       font-family: Times;
+       font-size: 2.5;
+       font-style: italic;
+}
+
+area::* {
+       text: name;
+       text-halo-radius: 0.5;
+       text-color: #000000;
+       text-halo-color: #ffffff;
+       text-halo-opacity: 0.8;
+       text-position: center;
+       font-family: Times;
+       font-size: 2.5;
+       font-style: italic;
 }
 
 /*
index 4944fcdd987de884971fc0ed2e5cfd8def596851..4a23c8d7643750393c9a9b25fd5a497b340fa36d 100644 (file)
@@ -14,6 +14,7 @@
 #include "leo.h"
 #include "osm.h"
 #include "sym.h"
+#include "labeller.h"
 
 static void sym_line_attrs(struct sym_line *l, struct svg *svg)
 {
@@ -180,7 +181,9 @@ static void sym_line_gen(struct osm_object *o, struct style_info *si, struct svg
       else
        osm_obj_warn(o, "Invalid dash pattern");
 
-      sym_plan(&sl->s, sym_zindex(o, si, casing ? 2 : 3));
+      if (o->type == OSM_TYPE_WAY)
+      labeller_add_line(&sl->s, sym_zindex(o, si, casing ? 2 : 3));
+      //sym_plan(&sl->s, sym_zindex(o, si, casing ? 2 : 3));
     }
 }
 
index c7c2be0a01f8c470757ae9416c4dd387f2135e21..3de12647cfed6854cac40b92ddc87dcea7b84790 100644 (file)
@@ -13,6 +13,8 @@
 #include "sym.h"
 #include "svg.h"
 
+#include "labeller.h"
+
 static void sym_point_draw(struct symbol *sym, struct svg *svg)
 {
   struct sym_point *p = (struct sym_point *) sym;
@@ -31,7 +33,8 @@ static void sym_point_draw(struct symbol *sym, struct svg *svg)
       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, "r", p->size / 2);
+      // svg_set_attr_dimen(svg, "r", p->size / 2); // DEBUG HACK
+      svg_set_attr_dimen(svg, "r", 3);
       break;
     // FIXME: Other shapes
     default:
@@ -91,7 +94,8 @@ static void sym_point_gen(struct osm_object *o, struct style_info *si, struct sv
       style_get_number(si, PROP_SYMBOL_FILL_OPACITY, &sp->fill_opacity);
     }
 
-  sym_plan(&sp->s, sym_zindex(o, si, 4));
+  //sym_plan(&sp->s, sym_zindex(o, si, 4));
+  labeller_add_point(&sp->s, o, sym_zindex(o, si, 4));
 }
 
 struct symbolizer symbolizer_point = {
@@ -138,7 +142,8 @@ static void sym_icon_gen(struct osm_object *o, struct style_info *si, struct svg
   // sir->opacity = 1;
   // style_get_number(si, PROP_ICON_OPACITY, &sir->opacity);
 
-  sym_plan(&sic->s, sym_zindex(o, si, 4));
+  labeller_add_point(&sic->s, o, sym_zindex(o, si, 4));
+  // sym_plan(&sic->s, sym_zindex(o, si, 4));
 }
 
 struct symbolizer symbolizer_icon = {
index 2666acd9f5d2e6f5984183750ad77b0a1ef2b7c8..66e834a05c42297f112792ae86708fc3d1ce538d 100644 (file)
@@ -17,6 +17,8 @@
 #include "sym.h"
 #include "map.h"
 
+#include "labeller.h"
+
 /*** Fonts ***/
 
 struct text_font {
@@ -455,7 +457,15 @@ static void sym_text_center(struct osm_object *o, struct style_info *si, osm_val
   st->x -= st->tw / 2;
   st->y += st->th - (st->th + st->td) / 2;
   text_fix_placement(st);
-  sym_plan(&st->s, sym_zindex(o, si, 4.9));
+  if (o->type == OSM_TYPE_WAY && !osm_way_cyclic_p((struct osm_way *) o))
+  {
+    labeller_add_linelabel(&st->s, o, sym_zindex(o, si, 4.9));
+  }
+  else
+  {
+//    sym_plan(&st->s, sym_zindex(o, si, 4.9));
+    labeller_add_arealabel(&st->s, o, sym_zindex(o, si, 4.9));
+  }
 }
 
 static void sym_text_way(struct osm_object *o, struct style_info *si, osm_val_t text)