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_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("DrawBorder", &map_draw_border),
38 CF_STRING("XMLInput", &map_xml_input),
39 CF_STRING("Projection", &map_projection),
40 CF_STRING("StyleSheet", &map_style_sheet),
41 CF_STRING("SVGOutput", &map_svg_output),
46 static void CONSTRUCTOR map_preinit(void)
48 cf_declare_section("Map", &map_cf, 0);
53 double page_offset_x, page_offset_y;
54 double page_map_width, page_map_height;
56 void map_set_scale(void)
58 double x_range = map_max_x - map_min_x;
59 double y_range = map_max_y - map_min_y;
60 double x_scale = page_width / x_range;
61 double y_scale = page_height / y_range;
62 map_scale = MIN(x_scale, y_scale);
63 page_map_width = x_range * map_scale;
64 page_map_height = y_range * map_scale;
65 page_offset_x = (page_width - page_map_width) / 2;
66 page_offset_y = (page_height - page_map_height) / 2;
68 msg(L_INFO, "Setting scale %.3g (orig window [%.6g,%.6g], page window [%.6g,%.6g]+[%.6g,%.6g] on [%.6g,%.6g])",
71 page_map_width, page_map_height,
72 page_offset_x, page_offset_y,
73 page_width, page_height);
75 double pmin_x = INFINITY, pmax_x = -INFINITY;
76 double pmin_y = INFINITY, pmax_y = -INFINITY;
77 double rmin_x = INFINITY, rmax_x = -INFINITY;
78 double rmin_y = INFINITY, rmax_y = -INFINITY;
79 CLIST_FOR_EACH(struct osm_node *, n, osm_obj_list[OSM_TYPE_NODE])
81 pmin_x = MIN(pmin_x, n->x);
82 pmax_x = MAX(pmax_x, n->x);
83 pmin_y = MIN(pmin_y, n->y);
84 pmax_y = MAX(pmax_y, n->y);
85 n->x = (n->x - map_min_x) * map_scale + page_offset_x;
86 n->y = page_height - page_offset_y - (n->y - map_min_y) * map_scale;
87 rmin_x = MIN(rmin_x, n->x);
88 rmax_x = MAX(rmax_x, n->x);
89 rmin_y = MIN(rmin_y, n->y);
90 rmax_y = MAX(rmax_y, n->y);
92 msg(L_INFO, "Bounds before scaling: [%.10g,%.10g] x [%.10g,%.10g]", pmin_x, pmax_x, pmin_y, pmax_y);
93 msg(L_INFO, "Bounds after scaling: [%.10g,%.10g] x [%.10g,%.10g]", rmin_x, rmax_x, rmin_y, rmax_y);
96 bool map_object_visible_p(struct osm_object *o)
104 struct osm_node *n = (struct osm_node *) o;
105 return (n->x >= page_offset_x - margin && n->x <= page_offset_x + page_map_width + margin &&
106 n->y >= page_offset_y - margin && n->y <= page_offset_y + page_map_height + margin);
110 struct osm_way *w = (struct osm_way *) o;
112 OSM_FOR_EACH_BEGIN(struct osm_object *, n, w->nodes)
114 ok |= map_object_visible_p(n);
119 case OSM_TYPE_RELATION:
121 struct osm_relation *r = (struct osm_relation *) o;
123 OSM_FOR_EACH_BEGIN(struct osm_object *, n, r->members)
125 ok |= map_object_visible_p(n);
130 case OSM_TYPE_MULTIPOLYGON:
131 return map_object_visible_p(&((struct osm_multipolygon *) o)->rel->o);