From 5108021e69b8d7ad55fd7811754b3f9ae36c6ef9 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sun, 27 Mar 2022 17:04:34 +0200 Subject: [PATCH] Experiments with simplication of ways --- Makefile | 2 +- leo.c | 4 ++ simplify.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++ simplify.h | 12 ++++++ 4 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 simplify.c create mode 100644 simplify.h diff --git a/Makefile b/Makefile index 1fe49f8..bf458e8 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ include $(BUILDSYS)/Maketop PROGS+=$(o)/leo CFLAGS+=$(LIBUCW_CFLAGS) -LEO_MODULES=leo xml osm svg svg-icon css-parse css-lex style css dict sym sym-point sym-line sym-text map shp fixed graph +LEO_MODULES=leo xml osm svg svg-icon css-parse css-lex style css dict sym sym-point sym-line sym-text map shp fixed graph simplify LEO_OBJECTS=$(addprefix $(o)/, $(addsuffix .o, $(LEO_MODULES))) $(o)/leo: $(LEO_OBJECTS) diff --git a/leo.c b/leo.c index 5c25ff6..b62d21b 100644 --- a/leo.c +++ b/leo.c @@ -18,6 +18,7 @@ #include "sym.h" #include "map.h" #include "graph.h" +#include "simplify.h" uns debug_dump_source, debug_dump_after_proj, debug_dump_after_scaling; uns debug_dump_multipolygons, debug_dump_css, debug_dump_styling, debug_dump_symbols; @@ -46,6 +47,7 @@ static const struct opt_section options = { } }; +#if 0 // FIXME: Make generic static void draw_scale(struct svg *svg) { @@ -110,6 +112,7 @@ static void draw_scale(struct svg *svg) scale_text(svg, width, 5, osm_val_encode("1 km")); svg_pop(svg); } +#endif int main(int argc UNUSED, char **argv) { @@ -121,6 +124,7 @@ int main(int argc UNUSED, char **argv) styles_init(); map_load_styles(); map_load_sources(); + simplify(); graph_build(); map_set_scale(); map_generalize(); diff --git a/simplify.c b/simplify.c new file mode 100644 index 0000000..a621027 --- /dev/null +++ b/simplify.c @@ -0,0 +1,124 @@ +/* + * Hic Est Leo -- Map Simplification + * + * (c) 2022 Martin Mares + */ + +#include "leo.h" + +#include +#include +#include + +#include +#include + +#include "osm.h" +#include "map.h" +#include "simplify.h" + +static struct mempool *simp_pool; + +struct coords { + double x, y; +}; + +struct simp_node_ref { + cnode n; + struct osm_node *to; +}; + +struct simp_way_ref { + cnode n; + struct osm_way *to; + bool is_end; +}; + +struct simp_node { + union { + struct coords c; + byte raw_coords[sizeof(struct coords)]; + }; + clist node_refs; + clist way_refs; + byte can_be_merged; +}; + +static void simp_hash_init_data(struct simp_node *s) +{ + clist_init(&s->node_refs); + clist_init(&s->way_refs); + s->can_be_merged = false; +} + +#define HASH_NODE struct simp_node +#define HASH_PREFIX(x) simp_hash_##x +#define HASH_KEY_MEMORY raw_coords +#define HASH_KEY_SIZE sizeof(struct coords) +#define HASH_WANT_LOOKUP +#define HASH_GIVE_INIT_DATA +#define HASH_USE_POOL simp_pool +#define HASH_TABLE_ALLOC +#include + +static bool simp_can_be_merged(struct simp_node *s) +{ + uint num_nodes = clist_size(&s->node_refs); + uint num_ways = clist_size(&s->way_refs); + + ASSERT(num_nodes); + if (num_nodes > 1) + { + msg(L_WARN, "Simplify: Multiple (%u) nodes at [%f, %f]", num_nodes, s->c.x, s->c.y); + return false; + } + + if (num_ways > 2) + return false; + + return false; +} + +static void simplify_source(struct data_source *ds) +{ + msg(L_INFO, "Simplifying source %s", ds->file); + simp_pool = mp_new(65536); + simp_hash_init(); + osm_this = ds->osm; + + CLIST_FOR_EACH(struct osm_way *, w, osm_this->obj_list[OSM_TYPE_WAY]) + { + struct osm_node *n_first = (struct osm_node *) osm_ref_head(&w->nodes); + struct osm_node *n_last = (struct osm_node *) osm_ref_tail(&w->nodes); + + OSM_FOR_EACH_BEGIN(struct osm_node *, n, w->nodes) + { + struct coords c = { .x = n->x, .y = n->y }; + struct simp_node *s = simp_hash_lookup((byte *) &c); + + struct simp_node_ref *nref = mp_alloc(simp_pool, sizeof(*nref)); + nref->to = n; + clist_add_tail(&s->node_refs, &nref->n); + + struct simp_way_ref *wref = mp_alloc(simp_pool, sizeof(*wref)); + wref->to = w; + wref->is_end = (n == n_first || n == n_last); + clist_add_tail(&s->way_refs, &wref->n); + } + OSM_FOR_EACH_END; + } + + HASH_FOR_ALL(simp_hash, s) + { + s->can_be_merged = simp_can_be_merged(s); + } + HASH_END_FOR; + + mp_delete(simp_pool); +} + +void simplify(void) +{ + CLIST_FOR_EACH(struct data_source *, ds, map_sources) + simplify_source(ds); +} diff --git a/simplify.h b/simplify.h new file mode 100644 index 0000000..423b879 --- /dev/null +++ b/simplify.h @@ -0,0 +1,12 @@ +/* + * Hic Est Leo -- Map Simplification + * + * (c) 2022 Martin Mares + */ + +#ifndef _LEO_SIMPLIFY_H +#define _LEO_SIMPLIFY_H + +void simplify(void); + +#endif -- 2.39.2