]> mj.ucw.cz Git - leo.git/blob - sym-point.c
Labelling: Bugfixes in get_closure
[leo.git] / sym-point.c
1 /*
2  *      Hic Est Leo -- Point and Icon Symbolizer
3  *
4  *      (c) 2014 Martin Mares <mj@ucw.cz>
5  */
6
7 #include <ucw/lib.h>
8
9 #include <stdio.h>
10
11 #include "leo.h"
12 #include "osm.h"
13 #include "sym.h"
14 #include "svg.h"
15
16 #include "labeller.h"
17
18 static void sym_point_draw(struct symbol *sym, struct svg *svg)
19 {
20   struct sym_point *p = (struct sym_point *) sym;
21   struct osm_object *o = sym->o;
22   struct osm_node *n = (struct osm_node *) o;
23
24   if (o->type != OSM_TYPE_NODE)
25     {
26       msg(L_ERROR, "Point symbolizer works only on nodes. It's a bug, isn't it?");
27       return;
28     }
29
30   switch (p->shape)
31     {
32     case VALUE_CIRCLE:
33       svg_push_element(svg, "circle");
34       svg_set_attr_dimen(svg, "cx", p->x);
35       svg_set_attr_dimen(svg, "cy", p->y);
36       svg_set_attr_dimen(svg, "r", p->size / 2);
37       break;
38     // FIXME: Other shapes
39     default:
40       osm_obj_warn(o, "Unknown symbol-shape %s", osm_val_decode(p->shape));
41       return;
42     }
43
44   // FIMXE: Use COLOR_NONE instead of do_stroke and do_fill
45   if (p->do_stroke)
46     {
47       svg_set_attr_color(svg, "stroke", p->stroke_color);
48       svg_set_attr_dimen(svg, "stroke-width", p->stroke_width);
49       if (p->stroke_opacity != 1)
50         svg_set_attr_float(svg, "stroke-opacity", p->stroke_opacity);
51     }
52   if (p->do_fill)
53     {
54       svg_set_attr_color(svg, "fill", p->fill_color);
55       if (p->fill_opacity != 1)
56         svg_set_attr_float(svg, "fill-opacity", p->fill_opacity);
57     }
58   else
59     svg_set_attr(svg, "fill", "none");
60   svg_pop(svg);
61 }
62
63 static void sym_point_gen(struct osm_object *o, struct style_info *si, struct svg *svg UNUSED)
64 {
65   if (o->type != OSM_TYPE_NODE)
66     return;
67
68   osm_val_t shape = style_get_ident(si, PROP_SYMBOL_SHAPE);
69   if (!shape)
70     return;
71
72   struct sym_point *sp = sym_point_new(o);
73   sp->shape = shape;
74
75   sp->size = 1;
76   style_get_number(si, PROP_SYMBOL_SIZE, &sp->size);
77
78   sp->stroke_width = 0.1;
79   sp->stroke_color = 0xffc800;
80   sp->stroke_opacity = 1;
81   if (style_get_color(si, PROP_SYMBOL_STROKE_COLOR, &sp->stroke_color) |
82       style_get_number(si, PROP_SYMBOL_STROKE_WIDTH, &sp->stroke_width))
83     {
84       sp->do_stroke = 1;
85       style_get_number(si, PROP_SYMBOL_STROKE_OPACITY, &sp->stroke_opacity);
86     }
87
88   sp->fill_color = 0x0000ff;
89   sp->fill_opacity = 1;
90   if (style_get_color(si, PROP_SYMBOL_FILL_COLOR, &sp->fill_color) || !sp->do_stroke)
91     {
92       sp->do_fill = 1;
93       style_get_number(si, PROP_SYMBOL_FILL_OPACITY, &sp->fill_opacity);
94     }
95
96   labeller_add_point(&sp->s, o, sym_zindex(o, si, 4));
97 }
98
99 struct symbolizer symbolizer_point = {
100   .name = "point",
101   .draw = sym_point_draw,
102   .gen = sym_point_gen,
103 };
104
105 struct sym_point *sym_point_new(struct osm_object *o)
106 {
107   return sym_new(SYMBOLIZER_POINT, o, sizeof(struct sym_point));
108 }
109
110 /*** Icons ***/
111
112 static void sym_icon_draw(struct symbol *sym, struct svg *svg)
113 {
114   struct sym_icon *i = (struct sym_icon *) sym;
115   svg_icon_put(svg, &i->sir);
116 }
117
118 static void sym_icon_gen(struct osm_object *o, struct style_info *si, struct svg *svg)
119 {
120   if (o->type != OSM_TYPE_NODE && o->type != OSM_TYPE_WAY && o->type != OSM_TYPE_MULTIPOLYGON)
121     return;
122
123   osm_val_t image = style_get_string(si, PROP_ICON_IMAGE);
124   if (!image)
125     return;
126
127   struct sym_icon *sic = sym_icon_new(o);
128   struct svg_icon *icon = svg_icon_load(svg, osm_val_decode(image));
129   struct svg_icon_request *sir = &sic->sir;
130   sir->icon = icon;
131
132   if (!osm_obj_center(o, &sir->x, &sir->y))
133     return;
134
135   sir->width = icon->width;
136   sir->height = icon->height;
137   style_scale(si, &sir->width, &sir->height, PROP_ICON_WIDTH, PROP_ICON_HEIGHT);
138
139   // FIXME
140   // sir->opacity = 1;
141   // style_get_number(si, PROP_ICON_OPACITY, &sir->opacity);
142
143   switch (o->type)
144   {
145     case OSM_TYPE_NODE:
146       labeller_add_point(&sic->s, o, sym_zindex(o, si, 4));
147       break;
148     case OSM_TYPE_WAY:
149     case OSM_TYPE_MULTIPOLYGON:
150       labeller_add_label(&sic->s, o, sym_zindex(o, si, 4));
151       break;
152   }
153 }
154
155 struct symbolizer symbolizer_icon = {
156   .name = "icon",
157   .draw = sym_icon_draw,
158   .gen = sym_icon_gen,
159 };
160
161 struct sym_icon *sym_icon_new(struct osm_object *o)
162 {
163   return sym_new(SYMBOLIZER_ICON, o, sizeof(struct sym_icon));
164 }