]> mj.ucw.cz Git - leo.git/commitdiff
Parametrized drawing of map scale mj
authorMartin Mares <mj@ucw.cz>
Sun, 7 Jun 2015 16:34:54 +0000 (18:34 +0200)
committerMartin Mares <mj@ucw.cz>
Sun, 7 Jun 2015 16:34:54 +0000 (18:34 +0200)
Previously, drawing of map scale was hard-wired to leo.c.

This patch adds special symbolizers, which are applied only
on explicit request. The first such symbolizer draws the map
scale, controlled by a set of style properties.

Makefile
dict-keys.t
dict-props.t
dict-values.t
leo.c
map.cf
style.c
style.h
sym-scale.c [new file with mode: 0644]
sym.c
sym.h

index e489923058a06d317ff5ecae64ef72a634b7c9f7..b1c6eee9bd45d964ff5e0241078503bfa202520c 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-scale sym-text map shp fixed
 LEO_OBJECTS=$(addprefix $(o)/, $(addsuffix .o, $(LEO_MODULES)))
 $(o)/leo: $(LEO_OBJECTS)
 
index 8cef8110667f92a0e4711fb0c80e817c17661a9c..a280fdf35694388337abd4071a9f03c4ddd08b4e 100644 (file)
@@ -5,6 +5,7 @@ addr:housenumber
 brand
 highway
 leisure
+leo:special
 name
 name:cz
 operator
index a164805d9b4c2a11b337e7bccd6b6d13bfb4223a..6ea8e57b2a6566f09a7d6e95c21a9b1e95870233 100644 (file)
@@ -47,6 +47,7 @@ text-offset-x
 text-offset-y
 text-opacity
 text-position
+tick-length
 z-index
 
 # The following properties come in couples, which must not be split
index 1d30763e12c2fcb7a0e101288ec1604218148940..8f2f34659465f472357b837d7791edc864ce978a 100644 (file)
@@ -24,6 +24,7 @@ normal
 outer
 right
 round
+scale
 square
 top
 true
diff --git a/leo.c b/leo.c
index c884ae75777be65c9f7c1a8fdbecfd3ad9e8144c..f8859e688c27999d8283b9880392c52e7fe0fa38 100644 (file)
--- a/leo.c
+++ b/leo.c
@@ -45,71 +45,6 @@ static const struct opt_section options = {
   }
 };
 
-// FIXME: Make generic
-static void draw_scale(struct svg *svg)
-{
-  double dist = 1000;
-  double width = dist * map_scale;
-  double x = page_width - 10 - width;
-  double y = 50;
-
-  svg_push_element(svg, "g");
-  svg_set_attr(svg, "id", "scale");
-  svg_set_attr_format(svg, "transform", "translate(%s,%s)", svg_format_dimen(svg, x), svg_format_dimen(svg, y));
-
-  for (int outline=1; outline>=0; outline--)
-    {
-      svg_push_element(svg, "g");
-      svg_set_attr(svg, "stroke-linecap", "square");
-      if (outline)
-       {
-         svg_set_attr_dimen(svg, "stroke-width", 1.5);
-         svg_set_attr_color(svg, "stroke", 0xffffff);
-       }
-      else
-       {
-         svg_set_attr_dimen(svg, "stroke-width", 0.5);
-         svg_set_attr_color(svg, "stroke", 0);
-       }
-
-      svg_push_element(svg, "line");
-      svg_set_attr_dimen(svg, "x1", 0);
-      svg_set_attr_dimen(svg, "y1", 0);
-      svg_set_attr_dimen(svg, "x2", width);
-      svg_set_attr_dimen(svg, "y2", 0);
-      svg_pop(svg);
-
-      for (int i=0; i<=10; i++)
-       {
-         double tick;
-         switch (i)
-           {
-           case 0:
-           case 10:
-             tick = 3;
-             break;
-           case 5:
-             tick = 2;
-             break;
-           default:
-             tick = 1;
-           }
-         svg_push_element(svg, "line");
-         svg_set_attr_dimen(svg, "x1", width * i/10);
-         svg_set_attr_dimen(svg, "y1", 0);
-         svg_set_attr_dimen(svg, "x2", width * i/10);
-         svg_set_attr_dimen(svg, "y1", -tick);
-         svg_pop(svg);
-       }
-
-      svg_pop(svg);
-    }
-
-  scale_text(svg, 0, 5, osm_val_encode("0"));
-  scale_text(svg, width, 5, osm_val_encode("1 km"));
-  svg_pop(svg);
-}
-
 int main(int argc UNUSED, char **argv)
 {
   cf_def_file = "map.cf";
@@ -162,8 +97,6 @@ int main(int argc UNUSED, char **argv)
 
   sym_draw_all(svg);
 
-  draw_scale(svg);
-
   if (map_clip)
     svg_pop(svg);
 
diff --git a/map.cf b/map.cf
index f1a33d3b2c16f61470c635d38261a28d8c54ec80..1ea08450a1570adb2a062b9183e0cea4bfdcd564 100644 (file)
--- a/map.cf
+++ b/map.cf
@@ -57,12 +57,19 @@ FixedObjects {
        # Fixed objects may be placed at specific positions on the paper
        # with specific tags. Remember to enable the "fixed" data source.
        Object {
+               # Image with a logo
                X 374
                Y 25
                Tag style:icon-image '"icons/logo.svg"'
                Tag style:icon-width 36
                Tag style:z-index 99
        }
+       Object {
+               # Map scale
+               X 325
+               Y 50
+               Tag leo:special scale
+       }
 }
 
 Debug {
diff --git a/style.c b/style.c
index b2a342ac267bf3ece60b0dc95b557ad3bfbc9d3d..d8fd4c5bce2aefb5b0fea3018d06ecea73688a87 100644 (file)
--- a/style.c
+++ b/style.c
@@ -125,6 +125,11 @@ static struct style_info *style_get_info(struct style_results *r, layer_t layer)
   return r->layers[layer];
 }
 
+void style_enable_default_layer(struct style_results *r)
+{
+  style_get_info(r, STYLE_LAYER_DEFAULT);
+}
+
 void style_set_by_layer(struct style_results *r, layer_t layer, struct style_prop *p)
 {
   if (layer == STYLE_LAYER_ALL)
diff --git a/style.h b/style.h
index 8abeb84efbbec6da175d9e64bbf70db9334beccf..eded29a9261dbccb47a84668877f8096e61e0f84 100644 (file)
--- a/style.h
+++ b/style.h
@@ -68,6 +68,7 @@ void style_init(struct style_results *r);
 void style_cleanup(struct style_results *r);
 void style_begin(struct style_results *r, struct osm_object *o);
 void style_end(struct style_results *r);
+void style_enable_default_layer(struct style_results *r);
 
 void style_set_by_layer(struct style_results *r, layer_t layer, struct style_prop *p);
 
diff --git a/sym-scale.c b/sym-scale.c
new file mode 100644 (file)
index 0000000..64b3233
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ *     Hic Est Leo -- Map Scale Symbolizer
+ *
+ *     (c) 2014--2015 Martin Mares <mj@ucw.cz>
+ */
+
+#include <ucw/lib.h>
+
+#include "leo.h"
+#include "osm.h"
+#include "map.h"
+#include "sym.h"
+
+static void sym_scale_draw(struct symbol *sym, struct svg *svg)
+{
+  struct sym_scale *sc = (struct sym_scale *) sym;
+  double dist = 1000;
+  double width = dist * map_scale;
+  struct osm_node *n = (struct osm_node *) sym->o;
+
+  svg_push_element(svg, "g");
+  // svg_set_attr(svg, "id", "scale");
+  svg_set_attr_format(svg, "transform", "translate(%s,%s)", svg_format_dimen(svg, n->x), svg_format_dimen(svg, n->y));
+
+  for (int outline=1; outline>=0; outline--)
+    {
+      svg_push_element(svg, "g");
+      svg_set_attr(svg, "stroke-linecap", "square");
+      if (outline)
+       {
+         svg_set_attr_dimen(svg, "stroke-width", sc->width + sc->casing_width);
+         svg_set_attr_color(svg, "stroke", sc->casing_color);
+       }
+      else
+       {
+         svg_set_attr_dimen(svg, "stroke-width", sc->width);
+         svg_set_attr_color(svg, "stroke", sc->color);
+       }
+
+      svg_push_element(svg, "line");
+      svg_set_attr_dimen(svg, "x1", 0);
+      svg_set_attr_dimen(svg, "y1", 0);
+      svg_set_attr_dimen(svg, "x2", width);
+      svg_set_attr_dimen(svg, "y2", 0);
+      svg_pop(svg);
+
+      for (int i=0; i<=10; i++)
+       {
+         double tick;
+         switch (i)
+           {
+           case 0:
+           case 10:
+             tick = 3;
+             break;
+           case 5:
+             tick = 2;
+             break;
+           default:
+             tick = 1;
+           }
+         tick *= sc->tick_length;
+         svg_push_element(svg, "line");
+         svg_set_attr_dimen(svg, "x1", width * i/10);
+         svg_set_attr_dimen(svg, "y1", 0);
+         svg_set_attr_dimen(svg, "x2", width * i/10);
+         svg_set_attr_dimen(svg, "y1", -tick);
+         svg_pop(svg);
+       }
+
+      svg_pop(svg);
+    }
+
+  scale_text(svg, 0, 5, osm_val_encode("0"));
+  scale_text(svg, width, 5, osm_val_encode("1 km"));
+  svg_pop(svg);
+}
+
+static void sym_scale_gen(struct osm_object *o, struct style_info *si, struct svg *svg UNUSED)
+{
+  if (o->type != OSM_TYPE_NODE)
+    die("Map scale must be a node");
+
+  struct sym_scale *sc = sym_scale_new(o);
+
+  sc->width = 0.5;
+  style_get_number(si, PROP_WIDTH, &sc->width);
+
+  sc->color = 0;
+  style_get_color(si, PROP_COLOR, &sc->color);
+
+  sc->casing_width = 0.5;
+  style_get_number(si, PROP_CASING_WIDTH, &sc->casing_width);
+
+  sc->casing_color = 0xffffff;
+  style_get_color(si, PROP_CASING_COLOR, &sc->casing_color);
+
+  sc->tick_length = 1;
+  style_get_number(si, PROP_TICK_LENGTH, &sc->tick_length);
+
+  sym_plan(&sc->s, sym_zindex(o, si, 4));
+}
+
+struct symbolizer symbolizer_scale = {
+  .name = "scale",
+  .draw = sym_scale_draw,
+  .gen = sym_scale_gen,
+  .special = VALUE_SCALE,
+};
+
+struct sym_scale *sym_scale_new(struct osm_object *o)
+{
+  return sym_new(SYMBOLIZER_SCALE, o, sizeof(struct sym_scale));
+}
diff --git a/sym.c b/sym.c
index 00d89416b3e798d4ce3f16405e2d420847771aaa..6a1436437dd4c96961b6db48ce234635d89548c0 100644 (file)
--- a/sym.c
+++ b/sym.c
@@ -1,7 +1,7 @@
 /*
  *     Hic Est Leo -- Symbols
  *
- *     (c) 2014 Martin Mares <mj@ucw.cz>
+ *     (c) 2014--2015 Martin Mares <mj@ucw.cz>
  */
 
 #include <ucw/lib.h>
@@ -19,7 +19,7 @@
 #undef CLAMP           // FIXME: Fix in libucw?
 #define CLAMP(x,min,max) ({ typeof(x) _t=x; (_t < min) ? min : (_t > max) ? max : _t; })       /** Clip a number @x to interval [@min,@max] **/
 
-static struct symbolizer *symbolizers[] = {
+static struct symbolizer *symbolizers[SYMBOLIZER_MAX] = {
   [SYMBOLIZER_INVALID] = NULL,
   [SYMBOLIZER_POINT] = &symbolizer_point,
   [SYMBOLIZER_ICON] = &symbolizer_icon,
@@ -27,6 +27,7 @@ static struct symbolizer *symbolizers[] = {
   [SYMBOLIZER_AREA] = &symbolizer_area,
   [SYMBOLIZER_TEXT] = &symbolizer_text,
   [SYMBOLIZER_LINEIMG] = &symbolizer_lineimg,
+  [SYMBOLIZER_SCALE] = &symbolizer_scale,
 };
 
 struct mempool *sym_mp;
@@ -118,11 +119,20 @@ z_index_t sym_zindex(struct osm_object *o, struct style_info *si, double default
 
 void sym_from_style(struct osm_object *o, struct style_results *sr, struct svg *svg)
 {
+  osm_val_t special = osm_obj_find_tag(o, KEY_LEO_SPECIAL);
+  if (special)
+    style_enable_default_layer(sr);
+
   for (uns i=0; i < sr->num_active_layers; i++)
     {
       for (uns j = SYMBOLIZER_INVALID + 1; j < SYMBOLIZER_MAX; j++)
-       if (symbolizers[j]->gen)
-         (symbolizers[j]->gen)(o, sr->layers[sr->active_layers[i]], svg);
+       {
+         struct symbolizer *sy = symbolizers[j];
+         // Either a generic symbolizer with a generic object,
+         // or a special symbolizer with its special object.
+         if (sy->special == special && sy->gen)
+           (sy->gen)(o, sr->layers[sr->active_layers[i]], svg);
+       }
     }
 }
 
diff --git a/sym.h b/sym.h
index e53409e7b8d9ecc9a35874bfae3ff72bdad4d1fa..1a45b7ba694d5db6548a6d12a6925aa3a1698089 100644 (file)
--- a/sym.h
+++ b/sym.h
@@ -1,7 +1,7 @@
 /*
  *     Hic Est Leo -- Symbolizers
  *
- *     (c) 2014 Martin Mares <mj@ucw.cz>
+ *     (c) 2014--2015 Martin Mares <mj@ucw.cz>
  */
 
 #ifndef _LEO_SYM_H
@@ -19,6 +19,7 @@ enum symbolizer_type {
   SYMBOLIZER_AREA,
   SYMBOLIZER_TEXT,
   SYMBOLIZER_LINEIMG,
+  SYMBOLIZER_SCALE,
   SYMBOLIZER_MAX,
 };
 
@@ -33,6 +34,7 @@ struct symbolizer {
   void (*draw)(struct symbol *sym, struct svg *svg);
   void (*gen)(struct osm_object *o, struct style_info *si, struct svg *svg);
   void (*init)(void);
+  osm_val_t special;           // Generated automatically only upon request
 };
 
 extern struct mempool *sym_mp;
@@ -148,4 +150,18 @@ struct sym_text *sym_text_new(struct osm_object *o);
 
 void scale_text(struct svg *svg, double x, double y, osm_val_t text);
 
+/* sym-scale.c */
+
+struct sym_scale {
+  struct symbol s;
+  double width;
+  color_t color;
+  double casing_width;
+  color_t casing_color;
+  double tick_length;
+};
+
+extern struct symbolizer symbolizer_scale;
+struct sym_scale *sym_scale_new(struct osm_object *o);
+
 #endif