]> mj.ucw.cz Git - leo.git/blobdiff - map.c
TODO
[leo.git] / map.c
diff --git a/map.c b/map.c
index 2aab9e2c66cdbe2687187277e37bc99ccea5de97..41bf483eeeddb7f2149f761c719470c4287b2c32 100644 (file)
--- a/map.c
+++ b/map.c
@@ -1,10 +1,17 @@
 /*
  *     Hic Est Leo -- Global Map Operations
  *
- *     (c) 2014 Martin Mares <mj@ucw.cz>
+ *     (c) 2014--2015 Martin Mares <mj@ucw.cz>
  */
 
-#include <ucw/lib.h>
+#include "leo.h"
+#include "osm.h"
+#include "shp.h"
+#include "map.h"
+#include "css.h"
+#include "sym.h"
+#include "fixed.h"
+
 #include <ucw/conf.h>
 #include <ucw/gary.h>
 #include <ucw/mempool.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;
 double page_width, page_height;
@@ -42,6 +43,8 @@ static struct cf_section map_style_cf = {
 static const char * const map_formats[] = {
   "invalid",
   "osmxml",
+  "fixed",
+  "shape",
 };
 
 static struct cf_section map_source_cf = {
@@ -51,6 +54,7 @@ static struct cf_section map_source_cf = {
     CF_STRING("File", P(file)),
     CF_LOOKUP("Format", P(format), map_formats),
     CF_LIST("StyleSheet", P(styles), &map_style_cf),
+    CF_INT("InlineStyles", P(inline_styles)),
     CF_END
   }
 #undef P
@@ -109,6 +113,8 @@ void map_set_scale(void)
   double rmin_y = INFINITY, rmax_y = -INFINITY;
   CLIST_FOR_EACH(struct data_source *, ds, map_sources)
     {
+      if (ds->format == DATA_SOURCE_FIXED)
+       continue;
       CLIST_FOR_EACH(struct osm_node *, n, ds->osm->obj_list[OSM_TYPE_NODE])
        {
          pmin_x = MIN(pmin_x, n->x);
@@ -217,29 +223,55 @@ 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);
-      if (debug_dump_source)
-       {
-         puts("=== Source data ===");
-         osm_dump();
-       }
-      osm_make_multipolygons();
+      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");
     }
 
-  msg(L_INFO, "Projecting");
-  osm_project(map_projection);
-  if (debug_dump_after_proj)
+  osm_stats();
+  if (debug_dump_source)
     {
-      puts("=== Map after projection ===");
+      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)
@@ -248,6 +280,43 @@ void map_load_sources(void)
     map_load_source(ds);
 }
 
+static void map_apply_inline_styles(struct osm_object *o, struct style_results *r)
+{
+  char *name = NULL;
+
+  CLIST_FOR_EACH(struct osm_tag *, t, o->tags)
+    {
+      const char *key = osm_key_decode(t->key);
+      if (!strncmp(key, "style:", 6))
+       {
+         key += 6;
+         layer_t layer = STYLE_LAYER_DEFAULT;
+         char *sep = strstr(key, "::");
+         if (sep)
+           {
+             if (sep[2])
+               {
+                 // XXX: Only layers defined in the main stylesheet can be modified
+                 layer = style_layer_encode_if_exists(sep+2);
+                 if (!layer)
+                   goto skip;
+               }
+             int keylen = sep - key;
+             char *t = mp_alloc(r->pool, keylen+1);
+             memcpy(t, key, keylen);
+             t[keylen] = 0;
+             key = t;
+           }
+
+         if (!name)
+           name = mp_printf(r->pool, "inline style of object #%ju", (uintmax_t) o->id);
+         struct style_prop *p= css_parse_prop(r->pool, name, key, osm_val_decode(t->val));
+         style_set_by_layer(r, layer, p);
+skip: ;
+       }
+    }
+}
+
 void map_apply_styles(struct svg *svg)
 {
   struct style_results r;
@@ -273,6 +342,8 @@ void map_apply_styles(struct svg *svg)
            style_begin(&r, o);
            CLIST_FOR_EACH(struct data_source_style *, ss, ds->styles)
              css_apply(ss->css, &r);
+           if (ds->inline_styles)
+             map_apply_inline_styles(o, &r);
            if (debug_dump_styling)
              style_dump(&r);
            sym_from_style(o, &r, svg);
@@ -280,5 +351,5 @@ void map_apply_styles(struct svg *svg)
          }
     }
 
-  // FIXME: Ought to destroy the style_results
+  style_cleanup(&r);
 }