// FIXME: Ought to destroy the style_results
}
-
-struct gen_context {
- struct osm_way *w;
- struct osm_ref **refs;
- uint in_nodes;
- uint out_nodes;
-};
-
-static void generalize_recursively(struct gen_context *gc, int first, int last)
-{
- if (last - first <= 1)
- return;
-
- double max_err = 0;
- struct osm_node *f = (struct osm_node *) gc->refs[first]->o, *l = (struct osm_node *) gc->refs[last]->o;
- double fx = f->x;
- double fy = f->y;
- double dx = l->x - fx;
- double dy = l->y - fy;
- double dd = dx*dx + dy*dy;
-
- for (int i = first + 1; i < last; i++)
- {
- struct osm_node *n = (struct osm_node *) gc->refs[i]->o;
- double nx = n->x - f->x;
- double ny = n->y - f->y;
- double p = dx*nx + dy*ny; // (px,py) = projection of (nx,ny) onto (dx,dy)
- double px = dx*p / dd;
- double py = dy*p / dd;
- double ex = px - nx; // (ex,ey) is the error vector: (nx,ny) minus its projection
- double ey = py - ny;
- double e = ex*ex + ey*ey;
- max_err = MAX(max_err, e);
- }
-
- double close = 1;
- if (max_err > close*close)
- {
- int mid = (first + last) / 2;
- ASSERT(first < mid && mid < last);
- generalize_recursively(gc, first, mid);
- clist_add_tail(&gc->w->nodes, &gc->refs[mid]->n);
- generalize_recursively(gc, mid, last);
- }
-}
-
-static void generalize_way(struct gen_context *gc, struct osm_way *w)
-{
- gc->w = w;
- GARY_RESIZE(gc->refs, 0);
-
- CLIST_FOR_EACH(struct osm_ref *, r, w->nodes)
- *GARY_PUSH(gc->refs) = r;
-
- int N = GARY_SIZE(gc->refs);
- if (N <= 2)
- return;
-
- gc->in_nodes += N;
-
-#if 0
- for (int i=0; i<N; i++)
- {
- struct osm_node *n = (struct osm_node *) gc->refs[i]->o;
- msg(L_DEBUG, "Generalize: @%d #%jd [%f,%f]", i, (intmax_t) n->o.id, n->x, n->y);
- }
-#endif
-
- clist_init(&w->nodes);
- clist_add_tail(&w->nodes, &gc->refs[0]->n);
- generalize_recursively(gc, 0, N-1);
- clist_add_tail(&w->nodes, &gc->refs[N-1]->n);
-
- CLIST_FOR_EACH(struct osm_ref *, r, w->nodes)
- gc->out_nodes++;
-}
-
-void map_generalize(void)
-{
- msg(L_INFO, "Generalizing ways");
- struct gen_context gc = { };
- GARY_INIT(gc.refs, 0);
-
- CLIST_FOR_EACH(struct data_source *, ds, map_sources)
- CLIST_FOR_EACH(struct osm_way *, w, ds->osm->obj_list[OSM_TYPE_WAY])
- generalize_way(&gc, w);
-
- GARY_FREE(gc.refs);
-
- msg(L_INFO, "Generalization: %u nodes in, %u nodes out", gc.in_nodes, gc.out_nodes);
-}