]> mj.ucw.cz Git - leo.git/blob - sym-point.c
9c159bfe6e7af406f46699ecbe9d196b0d66a910
[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); // DEBUG HACK
37       svg_set_attr_dimen(svg, "r", 3);
38       break;
39     // FIXME: Other shapes
40     default:
41       osm_obj_warn(o, "Unknown symbol-shape %s", osm_val_decode(p->shape));
42       return;
43     }
44
45   // FIMXE: Use COLOR_NONE instead of do_stroke and do_fill
46   if (p->do_stroke)
47     {
48       svg_set_attr_color(svg, "stroke", p->stroke_color);
49       svg_set_attr_dimen(svg, "stroke-width", p->stroke_width);
50       if (p->stroke_opacity != 1)
51         svg_set_attr_float(svg, "stroke-opacity", p->stroke_opacity);
52     }
53   if (p->do_fill)
54     {
55       svg_set_attr_color(svg, "fill", p->fill_color);
56       if (p->fill_opacity != 1)
57         svg_set_attr_float(svg, "fill-opacity", p->fill_opacity);
58     }
59   else
60     svg_set_attr(svg, "fill", "none");
61   svg_pop(svg);
62 }
63
64 static void sym_point_gen(struct osm_object *o, struct style_info *si, struct svg *svg UNUSED)
65 {
66   if (o->type != OSM_TYPE_NODE)
67     return;
68
69   osm_val_t shape = style_get_ident(si, PROP_SYMBOL_SHAPE);
70   if (!shape)
71     return;
72
73   struct sym_point *sp = sym_point_new(o);
74   sp->shape = shape;
75
76   sp->size = 1;
77   style_get_number(si, PROP_SYMBOL_SIZE, &sp->size);
78
79   sp->stroke_width = 0.1;
80   sp->stroke_color = 0xffc800;
81   sp->stroke_opacity = 1;
82   if (style_get_color(si, PROP_SYMBOL_STROKE_COLOR, &sp->stroke_color) |
83       style_get_number(si, PROP_SYMBOL_STROKE_WIDTH, &sp->stroke_width))
84     {
85       sp->do_stroke = 1;
86       style_get_number(si, PROP_SYMBOL_STROKE_OPACITY, &sp->stroke_opacity);
87     }
88
89   sp->fill_color = 0x0000ff;
90   sp->fill_opacity = 1;
91   if (style_get_color(si, PROP_SYMBOL_FILL_COLOR, &sp->fill_color) || !sp->do_stroke)
92     {
93       sp->do_fill = 1;
94       style_get_number(si, PROP_SYMBOL_FILL_OPACITY, &sp->fill_opacity);
95     }
96
97   //sym_plan(&sp->s, sym_zindex(o, si, 4));
98   labeller_add_point(&sp->s, o, sym_zindex(o, si, 4));
99 }
100
101 struct symbolizer symbolizer_point = {
102   .name = "point",
103   .draw = sym_point_draw,
104   .gen = sym_point_gen,
105 };
106
107 struct sym_point *sym_point_new(struct osm_object *o)
108 {
109   return sym_new(SYMBOLIZER_POINT, o, sizeof(struct sym_point));
110 }
111
112 /*** Icons ***/
113
114 static void sym_icon_draw(struct symbol *sym, struct svg *svg)
115 {
116   struct sym_icon *i = (struct sym_icon *) sym;
117   svg_icon_put(svg, &i->sir);
118 }
119
120 static void sym_icon_gen(struct osm_object *o, struct style_info *si, struct svg *svg)
121 {
122   if (o->type != OSM_TYPE_NODE && o->type != OSM_TYPE_WAY && o->type != OSM_TYPE_MULTIPOLYGON)
123     return;
124
125   osm_val_t image = style_get_string(si, PROP_ICON_IMAGE);
126   if (!image)
127     return;
128
129   struct sym_icon *sic = sym_icon_new(o);
130   struct svg_icon *icon = svg_icon_load(svg, osm_val_decode(image));
131   struct svg_icon_request *sir = &sic->sir;
132   sir->icon = icon;
133
134   if (!osm_obj_center(o, &sir->x, &sir->y))
135     return;
136
137   sir->width = icon->width;
138   sir->height = icon->height;
139   style_scale(si, &sir->width, &sir->height, PROP_ICON_WIDTH, PROP_ICON_HEIGHT);
140
141   // FIXME
142   // sir->opacity = 1;
143   // style_get_number(si, PROP_ICON_OPACITY, &sir->opacity);
144
145   switch (o->type)
146   {
147     case OSM_TYPE_NODE:
148       labeller_add_point(&sic->s, o, sym_zindex(o, si, 4));
149       break;
150     case OSM_TYPE_WAY:
151       if (!osm_way_cyclic_p((struct osm_way *) o))
152       {
153       labeller_add_linelabel(&sic->s, o, sym_zindex(o, si, 4));
154       break;
155       }
156     case OSM_TYPE_MULTIPOLYGON:
157       labeller_add_arealabel(&sic->s, o, sym_zindex(o, si, 4));
158       break;
159   }
160 }
161
162 struct symbolizer symbolizer_icon = {
163   .name = "icon",
164   .draw = sym_icon_draw,
165   .gen = sym_icon_gen,
166 };
167
168 struct sym_icon *sym_icon_new(struct osm_object *o)
169 {
170   return sym_new(SYMBOLIZER_ICON, o, sizeof(struct sym_icon));
171 }