]> mj.ucw.cz Git - leo.git/blobdiff - sym-scale.c
Parametrized drawing of map scale
[leo.git] / sym-scale.c
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));
+}