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