]> mj.ucw.cz Git - leo.git/commitdiff
Labelling: Another bunch of edits
authorKarryanna <karry@karryanna.cz>
Mon, 13 Apr 2015 09:08:41 +0000 (11:08 +0200)
committerKarryanna <karry@karryanna.cz>
Mon, 13 Apr 2015 09:08:41 +0000 (11:08 +0200)
labeller.c
labeller.h
sym-line.c

index 46c6839301131decc2afd627898515ba80bb5782..d64c67a0c7143a90d6d05d64e4d88e765f005d30 100644 (file)
@@ -27,7 +27,7 @@ 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 graph_edge **bfs_queue;
 static struct longline *longlines; int num_longlines;
 static struct buffer_line *buffer_line;
 static struct buffer_linelabel *buffer_linelabel;
@@ -37,6 +37,11 @@ struct eltpool *ep_individuals;
 struct individual **population1;
 struct individual **population2;
 
+int num_edges_dbg;
+int num_nodes;
+int num_edges = 0;
+int dbg_num_hits = 0;
+
 int conf_pop_size = 50;
 
 int conf_penalty_bound = 0;
@@ -123,10 +128,6 @@ void labeller_add_point(struct symbol *sym, struct osm_object *object, z_index_t
   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;
 
@@ -139,15 +140,22 @@ void labeller_add_point(struct symbol *sym, struct osm_object *object, z_index_t
   {
     case SYMBOLIZER_ICON:
       make_bitmap_icon(v, (struct sym_icon *) sym);
+      r->x = ((struct sym_icon *)sym)->sir.x;
+      r->y = ((struct sym_icon *)sym)->sir.y;
       break;
     case SYMBOLIZER_POINT:
       make_bitmap_point(v, (struct sym_point *) sym);
+      struct osm_node *n = (struct osm_node *) object;
+      r->x = n->x;
+      r->y = n->y;
       break;
     default:
       // Oops :)
       // FIXME
       return;
   }
+
+  printf("Inited point to [%.2f; %.2f]\n", r->x, r->y);
 }
 
 void labeller_add_line(struct symbol *sym, z_index_t zindex)
@@ -205,6 +213,8 @@ void make_graph(void)
         g_node = hash_new(ref->o->id);
         GARY_INIT(g_node->edges, 0);
         g_node->o = o_node;
+        g_node->id = ref->o->id;
+        g_node->num = num_nodes++;
       }
 
       if (! g_prev)
@@ -214,7 +224,8 @@ void make_graph(void)
         continue;
       }
 
-      struct graph_edge *e = mp_alloc(mp_edges, sizeof(struct graph_edge));
+      struct graph_edge *e = mp_alloc(mp_edges, sizeof(struct graph_edge)); num_edges_dbg++;
+      e->num = num_edges++;
       e->id = buffer_line[i].line->s.o->id;
       e->color = buffer_line[i].line->color;
       e->length = hypot(abs(o_prev->x - o_node->x), abs(o_prev->y - o_node->y));
@@ -226,21 +237,54 @@ void make_graph(void)
       e->longline = (uns) -1;
       e->text = NULL;
       e->sym = buffer_line[i].line;
+      e->dir = 0;
 
       struct graph_edge **edge = GARY_PUSH(g_prev->edges);
       *edge = e;
       edge = GARY_PUSH(g_node->edges);
       *edge = e;
+
+      g_prev = g_node;
+      o_prev = o_node;
     }
   }
 }
 
+void dump_graph(void)
+{
+  HASH_FOR_ALL(hash, node)
+  {
+    printf("* Node: (%d) #%ju [%.2f; %.2f]\n", node->num, node->id, node->o->x, node->o->y);
+    for (uns i=0; i<GARY_SIZE(node->edges); i++)
+    {
+      struct graph_edge *e = node->edges[i];
+      printf("\t edge (%d) #%ju to ", e->num, e->id);
+      if (node->edges[i]->n1->id == node->id)
+        printf("(%d) #%ju [%.2f; %.2f]\n", e->n2->num, e->n2->id, e->n2->o->x, e->n2->o->y);
+      else if (node->edges[i]->n2->id == node->id)
+        printf("(%d) #%ju [%.2f; %.2f]\n", e->n1->num, e->n1->id, e->n1->o->x, e->n1->o->y);
+      else
+        printf("BEWARE! BEWARE! BEWARE!\n");
+
+      printf("\t\t");
+      if (node->edges[i]->text) printf(" labelled %s;", osm_val_decode(node->edges[i]->text->text));
+      printf(" colored %d;", node->edges[i]->color);
+      printf("   length %.2f", node->edges[i]->length);
+      printf("\n");
+    }
+  }
+  HASH_END_FOR;
+}
+
 void label_graph(void)
 {
+printf("There are %u line labels requested\n", GARY_SIZE(buffer_linelabel));
   for (uns i=0; i<GARY_SIZE(buffer_linelabel); i++)
   {
+    printf("Labelling nodes of way %s\n", osm_val_decode(buffer_linelabel[i].text->text));
     CLIST_FOR_EACH(struct osm_ref *, ref, buffer_linelabel[i].way->nodes)
     {
+      printf("Looking for node %ju\n", ref->o->id);
       struct graph_node *n = hash_find(ref->o->id);
       if (n == NULL)
       {
@@ -248,10 +292,12 @@ void label_graph(void)
       }
       else
       {
+        printf("Searching among %u edges\n", GARY_SIZE(n->edges));
         for (uns j=0; j<GARY_SIZE(n->edges); j++)
         {
           if (n->edges[j]->id == buffer_linelabel[i].way->o.id)
           {
+            printf("Labelling node %ju\n", n->id);
             n->edges[j]->text = buffer_linelabel[i].text;
             n->edges[j]->zindex = buffer_linelabel[i].zindex;
           }
@@ -329,11 +375,13 @@ void join_edge(struct graph_edge *e, int dir)
   }
 }
 
-void bfs(void)
+void bfs2(void)
 {
   GARY_INIT(bfs_queue, 0);
   GARY_INIT(longlines, 0);
 
+  printf("Making longlines from %u causal lines, using %d graph edges\n", GARY_SIZE(buffer_line), num_edges_dbg);
+
   HASH_FOR_ALL(hash, node)
   {
     for (uns i=0; i<GARY_SIZE(node->edges); i++)
@@ -371,8 +419,209 @@ void bfs(void)
   GARY_FREE(bfs_queue);
 }
 
+void bfs_edge(struct graph_edge *e, struct graph_node *node, struct graph_node *anode, int dir)
+{
+  ASSERT(dir < 3);
+  struct graph_edge *candidate = NULL;
+
+  if ((e->num > 31) && (e->num < 48)) printf("Searching for neighbours of %d, in longline %u, BFS dir is %d, edge's dir is %d\n", e->num, e->longline, dir, e->dir);
+
+
+  for (uns i=0; i<GARY_SIZE(node->edges); i++)
+  {
+    struct graph_edge *other = node->edges[i];
+printf("Touching %d\n", other->num);
+if (other->num == 44) printf("Longline of 44 is %u\n", other->longline);
+    if ((other->longline != (uns) -1) && (other->longline != e->longline)) continue;
+
+    if (! other->visited) {
+    struct graph_edge **e_ptr = GARY_PUSH(bfs_queue);
+    *e_ptr = other;
+    other->visited = 1;
+    }
+
+    if (((other->n1->id == node->id) && (other->n2->id == anode->id)) ||
+        ((other->n2->id == node->id) && (other->n1->id == anode->id)))
+        continue;
+
+    if (((other->n1->id == node->id) || (other->n2->id == node->id)) &&
+        (e->text) && (other->text) && (e->text->text == other->text->text))
+    {
+      if (! candidate || (other->length > candidate->length))
+      candidate = other;
+    }
+  }
+
+  if (candidate)
+  {
+    struct graph_edge *other = candidate;
+dbg_num_hits++;
+      other->longline = e->longline;
+      other->dir = dir;
+      other->anode = (other->n1->id == node->id ? other->n2 : other->n1);
+      other->bnode = (other->n1->id == node->id ? other->n1 : other->n2);
+      switch (dir)
+      {
+        case 1:
+          e->prev = other;
+          other->next = e;
+          longlines[other->longline].first = other;
+          break;
+        case 2:
+          e->next = other;
+          other->prev = e;
+          break;
+        default:
+          printf("Oops\n");
+          ASSERT(0);
+      }
+  }
+}
+
+void bfs(void)
+{
+  for (uns i=0; i<GARY_SIZE(bfs_queue); i++)
+  {
+    struct graph_edge *cur = bfs_queue[i];
+    printf("Exploring new edge, %d\n", cur->num);
+    //ASSERT(! cur->visited);
+
+    cur->visited = 1;
+    if (cur->longline == (uns) -1)
+    {
+      GARY_PUSH(longlines);
+      cur->longline = num_longlines++;
+      longlines[cur->longline].first = cur;
+    }
+
+    if (!cur->anode)
+    {
+      bfs_edge(cur, cur->n1, cur->n2, 1);
+      bfs_edge(cur, cur->n2, cur->n1, 2);
+    }
+    else
+    {
+      bfs_edge(cur, cur->anode, cur->bnode, cur->dir);
+    }
+  }
+}
+
+void bfs_wrapper(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++)
+    {
+      if (! node->edges[i]->visited)
+      {
+        printf("Running new BFS\n");
+        GARY_RESIZE(bfs_queue, 0);
+        struct graph_edge **e = GARY_PUSH(bfs_queue);
+        *e = node->edges[i];
+        bfs();
+        //dump_longlines();
+        printf("Joined %d edges\n", dbg_num_hits); dbg_num_hits = 0;
+        printf("Planned %u edges\n", GARY_SIZE(bfs_queue));
+      }
+    }
+  }
+  HASH_END_FOR;
+
+  GARY_FREE(bfs_queue);
+}
+
+void oldbfs(void)
+{
+  printf("Starting outer BFS\n");
+  printf("There are %u buffered lines and %d eges\n", GARY_SIZE(buffer_line), num_edges_dbg);
+
+  GARY_INIT(bfs_queue, 0);
+  GARY_INIT(longlines, 0);
+
+  int dbg_bfs_continues = 0;
+
+  HASH_FOR_ALL(hash, node)
+  {
+    // FIXME: Skip if visited node
+
+    for (uns i=0; i<GARY_SIZE(node->edges); i++)
+    {
+      struct graph_edge *e = node->edges[i];
+
+      if (e->visited) continue;
+
+      // BFS itself
+      for (uns i1=0; i1<GARY_SIZE(e->n1->edges); i1++)
+      {
+        struct graph_edge *other = e->n1->edges[i1];
+        if (other->visited) { dbg_bfs_continues++; continue; }
+
+        if (((other->n1->id == e->n1->id) || (other->n2->id == e->n1->id)) &&
+            (e->text) && (other->text) && (e->text->text == other->text->text))
+        {
+//          printf("Hit\n");
+          other->visited = 1;
+        }
+      }
+      for (uns i2=0; i2<GARY_SIZE(e->n2->edges); i2++)
+      {
+        struct graph_edge *other = e->n2->edges[i2];
+        if (other->visited) {dbg_bfs_continues++; continue; }
+
+        if (((other->n1->id == e->n2->id) || (other->n2->id == e->n2->id)) &&
+            (e->text) && (other->text) && (e->text->text == other->text->text))
+        {
+//          printf("Hit\n");
+          other->visited = 1;
+        }
+      }
+    }
+  }
+
+  HASH_END_FOR;
+  printf("Total: %d hits, %d visited edges skipped\n", dbg_num_hits, dbg_bfs_continues);
+
+  GARY_FREE(bfs_queue);
+}
+
+void dump_longlines(void)
+{
+  for (uns i=0; i<GARY_SIZE(longlines); i++)
+  {
+    struct graph_edge *e = longlines[i].first;
+
+    printf("> Longline %u;", i);
+    if (longlines[i].first->text) printf(" labelled %s", osm_val_decode(longlines[i].first->text->text));
+    printf("\n");
+    while (e)
+    {
+      printf("\t#%ju (%d)", e->id, e->num);
+      switch (e->dir)
+      {
+      case 1:
+       printf("[%.2f; %.2f] -- #%u [%.2f; %.2f] (dir %d)\n", e->anode->o->x, e->anode->o->y, e->bnode->o->o.id, e->bnode->o->x, e->bnode->o->y, e->dir);
+       break;
+      case 2:
+       printf("[%.2f; %.2f] -- #%u [%.2f; %.2f] (dir %d)\n", e->bnode->o->x, e->bnode->o->y, e->anode->o->o.id, e->anode->o->x, e->anode->o->y, e->dir);
+       break;
+      case 0:
+       printf("[%.2f; %.2f] -- #%u [%.2f; %.2f] (dir %d)\n", e->n1->o->x, e->n1->o->y, e->n2->o->o.id, e->n2->o->x, e->n2->o->y, e->dir);
+       break;
+      default:
+        printf("%d\n", e->dir);
+        ASSERT(0);
+      }
+      e = e->next;
+    }
+  }
+}
+
 void make_segments(void)
 {
+printf("Analysing %u longlines\n", GARY_SIZE(longlines));
   for (uns i=0; i<GARY_SIZE(longlines); i++)
   {
     if (! longlines[i].first->text) continue;
@@ -409,7 +658,7 @@ printf("New longline\n");
       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);
+//printf("Segment [%.2f; %.2f] -- [%.2f; %.2f]\n", r->x1, r->y1, r->x2, r->y2);
 
       r->sym = e->sym;
       r->zindex = e->zindex;
@@ -426,12 +675,46 @@ printf("Segment [%.2f; %.2f] -- [%.2f; %.2f]\n", r->x1, r->y1, r->x2, r->y2);
   }
 }
 
+void dump_linelabel_requests(void)
+{
+  for (uns i=0; i<GARY_SIZE(requests_line); i++)
+  {
+    printf("Longline of %d segments, labelled %s\n", requests_line[i].num_segments, osm_val_decode(requests_line[i].segments[0].text->text));
+  }
+}
+
+void dump_individual(struct individual *individual)
+{
+  for (uns i=0; i<GARY_SIZE(individual->placements); i++)
+  {
+    struct placement *p = &(individual->placements[i]);
+
+    switch (p->request->type)
+    {
+      case REQUEST_POINT:
+        printf("Point at [%.2f; %.2f]\n", p->x, p->y);
+        break;
+      case REQUEST_LINELABEL: ;
+        struct request_line *rl = (struct request_line *) p->request;
+        printf("%d-segment longline %s\n", rl->num_segments, osm_val_decode(rl->segments[0].text->text));
+        break;
+      case REQUEST_AREALABEL: ;
+        struct request_area *ra = (struct request_area *) p->request;
+        printf("Area label %s at [%.2f; %.2f]\n", osm_val_decode(ra->sym->text), p->x, p->y);
+    }
+  }
+  printf("\nTotal penalty: %d\n", individual->penalty);
+}
+
 void labeller_label(void)
 {
   make_graph();
   label_graph();
-  bfs();
+dump_graph();
+  bfs_wrapper();
+dump_longlines();
   make_segments();
+dump_linelabel_requests();
 
 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));
 
@@ -441,6 +724,7 @@ printf("Having %u point requests, %u line requests and %u area requests\n", GARY
 
   printf("Dealing with %d requests\n", num_requests);
 
+/*
   while (! shall_terminate())
   {
     iteration++;
@@ -450,6 +734,9 @@ printf("Having %u point requests, %u line requests and %u area requests\n", GARY
     population2 = swp;
     pop2_ind = 0;
   }
+*/
+
+  dump_individual(population1[0]);
 
   for (uns i=0; i<GARY_SIZE(population1[0]->placements); i++)
   {
@@ -460,12 +747,14 @@ printf("Having %u point requests, %u line requests and %u area requests\n", GARY
         switch (rp->sym->type)
         {
           case SYMBOLIZER_POINT: ;
+//          printf("Moving point to final destination\n");
            struct sym_point *sp = (struct sym_point *) rp->sym;
-           sp->x = i*10;
-           sp->y = i*10;
+           sp->x = population1[0]->placements[i].x;
+           sp->y = population1[0]->placements[i].y;
             sym_plan((struct symbol *) sp, rp->zindex);
            break;
          case SYMBOLIZER_ICON: ;
+//          printf("Moving icon to final destination\n");
            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;
@@ -484,12 +773,19 @@ printf("Having %u point requests, %u line requests and %u area requests\n", GARY
         struct request_line *rl = (struct request_line *) population1[0]->placements[i].request;
         for (uns j=0; j<GARY_SIZE(rl->segments); 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);
+//          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;
+          rl->segments[j].text->x = population1[0]->placements[i].x;
+          rl->segments[j].text->y = population1[0]->placements[i].y;
           sym_plan((struct symbol *) rl->segments[j].text, rl->segments[j].zindex); // FIXME: z-index
         }
-
+        break;
+/*
+      case REQUEST_SEGMENT: ;
+        struct request_segment *rs = (struct request_segment *) population1[0]->placements[i].request;
+        printf("Segment!\n");
+*/
     }
   }
 
@@ -796,6 +1092,24 @@ void init_placement(struct placement *p, struct request *r)
   // FIXME
   p->request = r;
   p->processed = 0;
+  switch (r->type)
+  {
+    case REQUEST_POINT: ;
+      struct request_point *rp = (struct request_point *) r;
+      p->x = rp->x;
+      p->y = rp->y;
+      break;
+    case REQUEST_SEGMENT: ;
+      struct request_segment *rs = (struct request_segment *) r;
+      p->x = rs->x2;
+      p->y = rs->y2;
+      break;
+    case REQUEST_AREALABEL: ;
+      struct request_area *ra = (struct request_area *) r;
+      struct sym_text *st = ra->sym;
+      p->x = st->x;
+      p->y = st->y;
+  }
 }
 
 void init_individual(struct individual *i)
index 8f1b0fad9637b17c5176176878c087422e8a9bd0..f17bda5b406b8a754242f88602f0aecad794aa64 100644 (file)
@@ -114,6 +114,7 @@ struct graph_node
   osm_id_t id;
   struct osm_node *o;
   struct graph_edge **edges;
+  int num;
 };
 
 struct graph_edge
@@ -130,6 +131,10 @@ struct graph_edge
   struct sym_text *text;
   struct sym_line *sym;
   z_index_t zindex;
+  int dir;
+  struct graph_node *anode;
+  struct graph_node *bnode; // DEBUG PRINT
+  int num; // DEBUG
 };
 
 struct longline
index 4a23c8d7643750393c9a9b25fd5a497b340fa36d..20a26dcbcad553287c798d96800acad0c887a4c3 100644 (file)
@@ -182,7 +182,12 @@ static void sym_line_gen(struct osm_object *o, struct style_info *si, struct svg
        osm_obj_warn(o, "Invalid dash pattern");
 
       if (o->type == OSM_TYPE_WAY)
+      {
+      if (casing)
+        sym_plan(&sl->s, sym_zindex(o, si, 2));
+      else
       labeller_add_line(&sl->s, sym_zindex(o, si, casing ? 2 : 3));
+      }
       //sym_plan(&sl->s, sym_zindex(o, si, casing ? 2 : 3));
     }
 }