#include <ucw/conf.h>
#include <ucw/gary.h>
#include <ucw/mempool.h>
+#include <ucw/simple-lists.h>
#include <stdio.h>
#include <math.h>
#include "leo.h"
#include "osm.h"
#include "map.h"
+#include "css.h"
+#include "sym.h"
double map_min_x, map_min_y;
double map_max_x, map_max_y;
char *map_projection;
char *map_style_sheet;
char *map_svg_output;
+clist map_sources;
+
+static struct cf_section map_style_cf = {
+#define P(x) PTR_TO(struct data_source_style, x)
+ CF_TYPE(struct data_source_style),
+ CF_ITEMS {
+ CF_STRING("Name", P(name)),
+ CF_END
+ }
+#undef P
+};
+
+static const char * const map_formats[] = {
+ "invalid",
+ "osmxml",
+};
+
+static struct cf_section map_source_cf = {
+#define P(x) PTR_TO(struct data_source, x)
+ CF_TYPE(struct data_source),
+ CF_ITEMS {
+ CF_STRING("File", P(file)),
+ CF_LOOKUP("Format", P(format), map_formats),
+ CF_LIST("StyleSheet", P(styles), &map_style_cf),
+ CF_END
+ }
+#undef P
+};
static struct cf_section map_cf = {
CF_ITEMS {
CF_UNS("Clip", &map_clip),
CF_UNS("Rotate", &map_rotate),
CF_UNS("DrawBorder", &map_draw_border),
- CF_STRING("XMLInput", &map_xml_input),
+ CF_LIST("Source", &map_sources, &map_source_cf),
CF_STRING("Projection", &map_projection),
- CF_STRING("StyleSheet", &map_style_sheet),
CF_STRING("SVGOutput", &map_svg_output),
CF_END
}
double pmin_y = INFINITY, pmax_y = -INFINITY;
double rmin_x = INFINITY, rmax_x = -INFINITY;
double rmin_y = INFINITY, rmax_y = -INFINITY;
- CLIST_FOR_EACH(struct osm_node *, n, osm_obj_list[OSM_TYPE_NODE])
+ CLIST_FOR_EACH(struct data_source *, ds, map_sources)
{
- pmin_x = MIN(pmin_x, n->x);
- pmax_x = MAX(pmax_x, n->x);
- pmin_y = MIN(pmin_y, n->y);
- pmax_y = MAX(pmax_y, n->y);
- n->x = (n->x - map_min_x) * map_scale + page_offset_x;
- n->y = page_height - page_offset_y - (n->y - map_min_y) * map_scale;
- rmin_x = MIN(rmin_x, n->x);
- rmax_x = MAX(rmax_x, n->x);
- rmin_y = MIN(rmin_y, n->y);
- rmax_y = MAX(rmax_y, n->y);
+ CLIST_FOR_EACH(struct osm_node *, n, ds->osm->obj_list[OSM_TYPE_NODE])
+ {
+ pmin_x = MIN(pmin_x, n->x);
+ pmax_x = MAX(pmax_x, n->x);
+ pmin_y = MIN(pmin_y, n->y);
+ pmax_y = MAX(pmax_y, n->y);
+ n->x = (n->x - map_min_x) * map_scale + page_offset_x;
+ n->y = page_height - page_offset_y - (n->y - map_min_y) * map_scale;
+ rmin_x = MIN(rmin_x, n->x);
+ rmax_x = MAX(rmax_x, n->x);
+ rmin_y = MIN(rmin_y, n->y);
+ rmax_y = MAX(rmax_y, n->y);
+ }
}
msg(L_INFO, "Bounds before scaling: [%.10g,%.10g] x [%.10g,%.10g]", pmin_x, pmax_x, pmin_y, pmax_y);
msg(L_INFO, "Bounds after scaling: [%.10g,%.10g] x [%.10g,%.10g]", rmin_x, rmax_x, rmin_y, rmax_y);
+
+ if (debug_dump_after_scaling)
+ {
+ puts("=== Map after scaling ===");
+ CLIST_FOR_EACH(struct data_source *, ds, map_sources)
+ {
+ osm_this = ds->osm;
+ osm_dump();
+ }
+ }
}
bool map_object_visible_p(struct osm_object *o)
ASSERT(0);
}
}
+
+void map_load_styles(void)
+{
+ clist style_cache;
+ clist_init(&style_cache);
+
+ CLIST_FOR_EACH(struct data_source *, ds, map_sources)
+ {
+ CLIST_FOR_EACH(struct data_source_style *, ss, ds->styles)
+ {
+ CLIST_FOR_EACH(struct simp_node *, n, style_cache)
+ {
+ struct data_source_style *x = n->p;
+ if (!strcmp(x->name, ss->name))
+ {
+ ss->css = x->css;
+ break;
+ }
+ }
+ if (!ss->css)
+ {
+ msg(L_DEBUG, "Loading style sheet %s", ss->name);
+ ss->css = css_load(ss->name);
+
+ if (debug_dump_css)
+ {
+ printf("=== Stylesheet %s ===", ss->name);
+ css_dump(ss->css);
+ }
+
+ simp_append(cf_get_pool(), &style_cache)->p = ss;
+ }
+ }
+ }
+}
+
+static void map_load_source(struct data_source *ds)
+{
+ ds->osm = osm_init();
+
+ switch (ds->format)
+ {
+ case DATA_SOURCE_OSMXML:
+ msg(L_INFO, "Parsing %s as OSM XML", ds->file);
+ osm_xml_parse(ds->file);
+ if (debug_dump_source)
+ {
+ puts("=== Source data ===");
+ osm_dump();
+ }
+ osm_make_multipolygons();
+ break;
+ default:
+ die("Invalid data source format");
+ }
+
+ msg(L_INFO, "Projecting");
+ osm_project(map_projection);
+ if (debug_dump_after_proj)
+ {
+ puts("=== Map after projection ===");
+ osm_dump();
+ }
+}
+
+void map_load_sources(void)
+{
+ CLIST_FOR_EACH(struct data_source *, ds, map_sources)
+ map_load_source(ds);
+}
+
+void map_apply_styles(struct svg *svg)
+{
+ struct style_results r;
+ style_init(&r);
+
+ CLIST_FOR_EACH(struct data_source *, ds, map_sources)
+ {
+ msg(L_INFO, "Applying stylesheet on %s", ds->file);
+ for (uns i = OSM_TYPE_NODE; i <= OSM_TYPE_MULTIPOLYGON; i++)
+ CLIST_FOR_EACH(struct osm_object *, o, ds->osm->obj_list[i])
+ {
+ if (debug_dump_styling)
+ {
+ puts("===============================");
+ osm_obj_dump(o);
+ }
+ if (!map_object_visible_p(o))
+ {
+ if (debug_dump_styling)
+ printf("--> invisible\n");
+ continue;
+ }
+ style_begin(&r, o);
+ CLIST_FOR_EACH(struct data_source_style *, ss, ds->styles)
+ css_apply(ss->css, &r);
+ if (debug_dump_styling)
+ style_dump(&r);
+ sym_from_style(o, &r, svg);
+ style_end(&r);
+ }
+ }
+
+ // FIXME: Ought to destroy the style_results
+}