2 * Hic Est Leo -- Global Map Operations
4 * (c) 2014 Martin Mares <mj@ucw.cz>
10 #include <ucw/mempool.h>
19 double map_min_x, map_min_y;
20 double map_max_x, map_max_y;
21 double page_width, page_height;
22 uns map_clip, map_rotate, map_draw_border;
25 char *map_style_sheet;
28 static struct cf_section map_cf = {
30 CF_DOUBLE("MinX", &map_min_x),
31 CF_DOUBLE("MinY", &map_min_y),
32 CF_DOUBLE("MaxX", &map_max_x),
33 CF_DOUBLE("MaxY", &map_max_y),
34 CF_DOUBLE("PageWidth", &page_width),
35 CF_DOUBLE("PageHeight", &page_height),
36 CF_UNS("Clip", &map_clip),
37 CF_UNS("Rotate", &map_rotate),
38 CF_UNS("DrawBorder", &map_draw_border),
39 CF_STRING("XMLInput", &map_xml_input),
40 CF_STRING("Projection", &map_projection),
41 CF_STRING("StyleSheet", &map_style_sheet),
42 CF_STRING("SVGOutput", &map_svg_output),
47 static void CONSTRUCTOR map_preinit(void)
49 cf_declare_section("Map", &map_cf, 0);
54 double page_offset_x, page_offset_y;
55 double page_map_width, page_map_height;
57 void map_set_scale(void)
59 double x_range = map_max_x - map_min_x;
60 double y_range = map_max_y - map_min_y;
61 double x_scale = page_width / x_range;
62 double y_scale = page_height / y_range;
63 map_scale = MIN(x_scale, y_scale);
64 page_map_width = x_range * map_scale;
65 page_map_height = y_range * map_scale;
66 page_offset_x = (page_width - page_map_width) / 2;
67 page_offset_y = (page_height - page_map_height) / 2;
69 msg(L_INFO, "Setting scale %.3g (orig window [%.6g,%.6g], page window [%.6g,%.6g]+[%.6g,%.6g] on [%.6g,%.6g])",
72 page_map_width, page_map_height,
73 page_offset_x, page_offset_y,
74 page_width, page_height);
76 double pmin_x = INFINITY, pmax_x = -INFINITY;
77 double pmin_y = INFINITY, pmax_y = -INFINITY;
78 double rmin_x = INFINITY, rmax_x = -INFINITY;
79 double rmin_y = INFINITY, rmax_y = -INFINITY;
80 CLIST_FOR_EACH(struct osm_node *, n, osm_obj_list[OSM_TYPE_NODE])
82 pmin_x = MIN(pmin_x, n->x);
83 pmax_x = MAX(pmax_x, n->x);
84 pmin_y = MIN(pmin_y, n->y);
85 pmax_y = MAX(pmax_y, n->y);
86 n->x = (n->x - map_min_x) * map_scale + page_offset_x;
87 n->y = page_height - page_offset_y - (n->y - map_min_y) * map_scale;
88 rmin_x = MIN(rmin_x, n->x);
89 rmax_x = MAX(rmax_x, n->x);
90 rmin_y = MIN(rmin_y, n->y);
91 rmax_y = MAX(rmax_y, n->y);
93 msg(L_INFO, "Bounds before scaling: [%.10g,%.10g] x [%.10g,%.10g]", pmin_x, pmax_x, pmin_y, pmax_y);
94 msg(L_INFO, "Bounds after scaling: [%.10g,%.10g] x [%.10g,%.10g]", rmin_x, rmax_x, rmin_y, rmax_y);
97 bool map_object_visible_p(struct osm_object *o)
105 struct osm_node *n = (struct osm_node *) o;
106 return (n->x >= page_offset_x - margin && n->x <= page_offset_x + page_map_width + margin &&
107 n->y >= page_offset_y - margin && n->y <= page_offset_y + page_map_height + margin);
111 struct osm_way *w = (struct osm_way *) o;
113 OSM_FOR_EACH_BEGIN(struct osm_object *, n, w->nodes)
115 ok |= map_object_visible_p(n);
120 case OSM_TYPE_RELATION:
122 struct osm_relation *r = (struct osm_relation *) o;
124 OSM_FOR_EACH_BEGIN(struct osm_object *, n, r->members)
126 ok |= map_object_visible_p(n);
131 case OSM_TYPE_MULTIPOLYGON:
132 return map_object_visible_p(&((struct osm_multipolygon *) o)->rel->o);