X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=map.c;h=bbcd7463b1f33de9864a3becb632b2b8c2c3f50e;hb=refs%2Fheads%2Flabelling;hp=455d7aab19c3206c95b81ed79df881d4163790e3;hpb=a732e5a272c5a1a30abc8c8f830583c75f334b96;p=leo.git diff --git a/map.c b/map.c index 455d7aa..bbcd746 100644 --- a/map.c +++ b/map.c @@ -8,13 +8,18 @@ #include #include #include +#include #include #include #include "leo.h" #include "osm.h" +#include "shp.h" #include "map.h" +#include "css.h" +#include "sym.h" +#include "fixed.h" double map_min_x, map_min_y; double map_max_x, map_max_y; @@ -24,6 +29,36 @@ char *map_xml_input; 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", + "fixed", + "shape", +}; + +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 { @@ -36,9 +71,8 @@ static struct cf_section map_cf = { 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 } @@ -77,21 +111,34 @@ void map_set_scale(void) 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) @@ -134,3 +181,134 @@ 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(); + + bool need_mp = 0; + bool need_proj = 0; + + switch (ds->format) + { + case DATA_SOURCE_OSMXML: + msg(L_INFO, "Parsing %s as OSM XML", ds->file); + if (!ds->file) + die("OSM XML data sources must have a file name"); + osm_xml_parse(ds->file); + need_mp = 1; + need_proj = 1; + break; + case DATA_SOURCE_FIXED: + msg(L_INFO, "Adding fixed objects"); + if (!ds->file) + ds->file = "fixed"; + fixed_add(); + break; + case DATA_SOURCE_SHAPE: + msg(L_INFO, "Parsing %s as shape file", ds->file); + if (!ds->file) + die("Shape data sources must have a file name"); + shp_parse(ds->file); + need_proj = 1; + break; + default: + die("Invalid data source format"); + } + + osm_stats(); + if (debug_dump_source) + { + puts("=== Source data ==="); + osm_dump(); + } + if (need_mp) + osm_make_multipolygons(); + + if (need_proj) + { + 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 +}