void item_bin_copy_coord(struct item_bin *ib, struct item_bin *from, int dir) { struct coord *c=(struct coord *)(from+1); int i,count=from->clen/2; if (dir >= 0) { item_bin_add_coord(ib, c, count); return; } for (i = 1 ; i <= count ; i++) item_bin_add_coord(ib, &c[count-i], 1); }
void item_bin_bbox(struct item_bin *ib, struct rect *r) { struct coord c; item_bin_add_coord(ib, &r->l, 1); c.x=r->h.x; c.y=r->l.y; item_bin_add_coord(ib, &c, 1); item_bin_add_coord(ib, &r->h, 1); c.x=r->l.x; c.y=r->h.y; item_bin_add_coord(ib, &c, 1); item_bin_add_coord(ib, &r->l, 1); }
void clip_polygon(struct item_bin *ib, struct rect *r, struct tile_parameter *param, struct item_bin_sink *out) { int count_in=ib->clen/2; struct coord *pin,*p,*s,pi; char *buffer1=g_alloca(sizeof(char)*(ib->len*4+ib->clen*7+32)); struct item_bin *ib1=(struct item_bin *)buffer1; char *buffer2=g_alloca(sizeof(char)*(ib->len*4+ib->clen*7+32)); struct item_bin *ib2=(struct item_bin *)buffer2; struct item_bin *ib_in,*ib_out; int edge,i; ib_out=ib1; ib_in=ib; for (edge = 0 ; edge < 4 ; edge++) { count_in=ib_in->clen/2; pin=(struct coord *)(ib_in+1); p=pin; s=pin+count_in-1; item_bin_init(ib_out, ib_in->type); for (i = 0 ; i < count_in ; i++) { if (geom_is_inside(p, r, edge)) { if (! geom_is_inside(s, r, edge)) { geom_poly_intersection(s,p,r,edge,&pi); item_bin_add_coord(ib_out, &pi, 1); } item_bin_add_coord(ib_out, p, 1); } else { if (geom_is_inside(s, r, edge)) { geom_poly_intersection(p,s,r,edge,&pi); item_bin_add_coord(ib_out, &pi, 1); } } s=p; p++; } if (ib_in == ib1) { ib_in=ib2; ib_out=ib1; } else { ib_in=ib1; ib_out=ib2; } } if (ib_in->clen) { if (param->attr_to_copy) item_bin_copy_attr(ib_in, ib, param->attr_to_copy); item_bin_write_clipped(ib_in, param, out); } }
void phase1_map(GList *maps, FILE *out_ways, FILE *out_nodes) { struct map_rect *mr; struct item *item; int count; struct coord ca[phase1_coord_max]; struct attr attr; struct item_bin *item_bin; while (maps) { mr=map_rect_new(maps->data, NULL); while ((item = map_rect_get_item(mr))) { count=item_coord_get(item, ca, item->type < type_line ? 1: phase1_coord_max); item_bin=init_item(item->type); item_bin_add_coord(item_bin, ca, count); while (item_attr_get(item, attr_any, &attr)) { if (attr.type >= attr_type_string_begin && attr.type <= attr_type_string_end) { attr.u.str=map_convert_string(maps->data, attr.u.str); if (attr.u.str) { item_bin_add_attr(item_bin, &attr); map_convert_free(attr.u.str); } } else item_bin_add_attr(item_bin, &attr); } if (item->type >= type_line) item_bin_write(item_bin, out_ways); else item_bin_write(item_bin, out_nodes); } map_rect_destroy(mr); maps=g_list_next(maps); } }
void phase1_map(struct map *map, FILE *out_ways, FILE *out_nodes) { struct map_rect *mr=map_rect_new(map, NULL); struct item *item; int count,max=16384; struct coord ca[max]; struct attr attr; while ((item = map_rect_get_item(mr))) { count=item_coord_get(item, ca, item->type < type_line ? 1: max); item_bin_init(item_bin, item->type); item_bin_add_coord(item_bin, ca, count); while (item_attr_get(item, attr_any, &attr)) { if (attr.type >= attr_type_string_begin && attr.type <= attr_type_string_end) { attr.u.str=map_convert_string(map, attr.u.str); item_bin_add_attr(item_bin, &attr); map_convert_free(attr.u.str); } else item_bin_add_attr(item_bin, &attr); } if (item->type >= type_line) item_bin_write(item_bin, out_ways); else item_bin_write(item_bin, out_nodes); } map_rect_destroy(mr); }
void item_bin_add_coord_reverse(struct item_bin *ib, struct coord *c, int count) { int i; for (i = count-1 ; i >= 0 ; i--) item_bin_add_coord(ib, &c[i], 1); }
void clip_line(struct item_bin *ib, struct rect *r, struct tile_parameter *param, struct item_bin_sink *out) { char *buffer=g_alloca(sizeof(char)*(ib->len*4+32)); struct item_bin *ib_new=(struct item_bin *)buffer; struct coord *pa=(struct coord *)(ib+1); int count=ib->clen/2; struct coord p1,p2; int i,code; item_bin_init(ib_new, ib->type); for (i = 0 ; i < count ; i++) { if (i) { p1.x=pa[i-1].x; p1.y=pa[i-1].y; p2.x=pa[i].x; p2.y=pa[i].y; /* 0 = invisible, 1 = completely visible, 3 = start point clipped, 5 = end point clipped, 7 both points clipped */ code=geom_clip_line_code(&p1, &p2, r); #if 1 if (((code == 1 || code == 5) && ib_new->clen == 0) || (code & 2)) { item_bin_add_coord(ib_new, &p1, 1); } if (code) { item_bin_add_coord(ib_new, &p2, 1); } if (i == count-1 || (code & 4)) { if (param->attr_to_copy) item_bin_copy_attr(ib_new, ib, param->attr_to_copy); if (ib_new->clen) item_bin_write_clipped(ib_new, param, out); item_bin_init(ib_new, ib->type); } #else if (code) { item_bin_init(ib_new, ib->type); item_bin_add_coord(ib_new, &p1, 1); item_bin_add_coord(ib_new, &p2, 1); if (param->attr_to_copy) item_bin_copy_attr(ib_new, ib, param->attr_to_copy); item_bin_write_clipped(ib_new, param, out); } #endif } } }
static void ch_process_node(FILE *out, int node, int resolve) { int first_edge_id=nodes[node].first_edge; int last_edge_id=nodes[node+1].first_edge; int edge_id; struct ch_edge ch_edge; struct item_bin *item_bin; struct edge_hash_item fwd,rev; int oldnode; memset(&ch_edge, 0, sizeof(ch_edge)); item_bin=init_item(type_ch_node); oldnode=GPOINTER_TO_INT(g_hash_table_lookup(newnode_hash, GINT_TO_POINTER(node))); #if 0 dbg(lvl_debug,"0x%x,0x%x\n",node_index[oldnode].x,node_index[oldnode].y); #endif item_bin_add_coord(item_bin, &node_index[oldnode], 1); fwd.first=oldnode; rev.last=oldnode; for (edge_id = first_edge_id ; edge_id < last_edge_id ; edge_id++) { if (resolve) { struct edge *edge=&edges[edge_id]; int oldnode=GPOINTER_TO_INT(g_hash_table_lookup(newnode_hash, GINT_TO_POINTER((int)edge->target))); struct item_id *id; ch_edge.weight=edge->weight; fwd.last=oldnode; rev.first=oldnode; ch_edge.flags=edge->flags & 3; if (edge->scmiddle == 67108863) { id=g_hash_table_lookup(edge_hash, &fwd); if (!id) { ch_edge.flags|=8; id=g_hash_table_lookup(edge_hash, &rev); } if (id == NULL) { fprintf(stderr,"Shortcut %d Weight %d\n",edge->scmiddle,edge->weight); fprintf(stderr,"Neither %d-%d nor %d-%d exists\n",fwd.first,fwd.last,rev.first,rev.last); exit(1); } else { ch_edge.middle=*id; #if 0 dbg(lvl_debug,"middle street id for is "ITEM_ID_FMT"\n",ITEM_ID_ARGS(*id)); #endif } } else { ch_edge.flags|=4; id=g_hash_table_lookup(sgr_nodes_hash, GINT_TO_POINTER((int)edge->scmiddle)); dbg_assert(id != NULL); ch_edge.middle=*id; #if 0 dbg(lvl_debug,"middle node id for is "ITEM_ID_FMT"\n",ITEM_ID_ARGS(*id)); #endif } id=g_hash_table_lookup(sgr_nodes_hash, GINT_TO_POINTER((int)edge->target)); #if 0 dbg(lvl_debug,"id for %d is "ITEM_ID_FMT"\n",edge->target,ITEM_ID_ARGS(*id)); #endif if (id == NULL) { fprintf(stderr,"Failed to look up target %d\n",edge->target); } else { ch_edge.target=*id; } } item_bin_add_attr_data(item_bin,attr_ch_edge,&ch_edge,sizeof(ch_edge)); } item_bin_write(item_bin, out); }
static GList * process_boundaries_finish(GList *boundaries_list) { //fprintf(stderr,"process_boundaries_finish:001\n"); GList *l, *sl, *l2, *ln; GList *ret = NULL; l = boundaries_list; char *f1_name = NULL; char *f2_name = NULL; long long b_counter_1 = 0; long long nodes_counter_ = 0; long long ways_counter_ = 0; while (l) { struct boundary *boundary = l->data; int first = 1; FILE *f = NULL, *fu = NULL; b_counter_1++; if ((b_counter_1 % 500) == 0) { fprintf(stderr,"boundaries_f1:B:%lld\n", b_counter_1); } //fprintf(stderr,"process_boundaries_finish:002\n"); // only lowercase country code if (boundary->iso2) { int i99; for (i99 = 0; boundary->iso2[i99]; i99++) { boundary->iso2[i99] = tolower(boundary->iso2[i99]); } } // only lowercase country code if (boundary->country) { //fprintf(stderr,"process_boundaries_finish:003\n"); char *name = g_strdup_printf("country_%s_poly", boundary->iso2); f1_name = g_strdup_printf("country_%s_poly", boundary->iso2); f = tempfile("", name, 1); g_free(name); } // calc bounding box first = 1; nodes_counter_ = 0; ways_counter_ = 0; sl = boundary->segments; while (sl) { struct geom_poly_segment *gs = sl->data; struct coord *c = gs->first; while (c <= gs->last) { if (first) { boundary->r.l = *c; boundary->r.h = *c; first = 0; } else { bbox_extend(c, &boundary->r); } c++; nodes_counter_++; } sl = g_list_next(sl); ways_counter_++; } //fprintf(stderr, "relid:%lld\n", item_bin_get_relationid(boundary->ib)); //fprintf(stderr, "ways:%lld nodes:%lld\n", ways_counter_, nodes_counter_); boundary->sorted_segments = geom_poly_segments_sort(boundary->segments, geom_poly_segment_type_way_right_side); sl = boundary->sorted_segments; first = 1; while (sl) { //fprintf(stderr,"process_boundaries_finish:004.1\n"); struct geom_poly_segment *gs = sl->data; struct coord *c = gs->first; /* while (c <= gs->last) { if (first) { boundary->r.l = *c; boundary->r.h = *c; first = 0; } else { bbox_extend(c, &boundary->r); } c++; //fprintf(stderr,"process_boundaries_finish:004.2 lx=%d ly=%d hx=%d hy=%d\n",boundary->r.l.x,boundary->r.l.y,boundary->r.h.x,boundary->r.h.y); } */ if (f) { struct item_bin *ib = item_bin_2; item_bin_init(ib, type_selected_line); item_bin_add_coord(ib, gs->first, gs->last - gs->first + 1); item_bin_write(ib, f); } if (boundary->country) { if (!coord_is_equal(*gs->first, *gs->last)) { if (!fu) { char *name = g_strdup_printf("country_%s_broken", boundary->iso2); f2_name = g_strdup_printf("country_%s_broken", boundary->iso2); fprintf(stderr, "*BROKEN* country_%s_broken\n", boundary->iso2); fu = tempfile("", name, 1); g_free(name); } struct item_bin *ib = item_bin_2; item_bin_init(ib, type_selected_point); item_bin_add_coord(ib, gs->first, 1); item_bin_write(ib, fu); item_bin_init(ib, type_selected_point); item_bin_add_coord(ib, gs->last, 1); item_bin_write(ib, fu); } } sl = g_list_next(sl); if (f2_name) { tempfile_unlink("", f2_name); g_free(f2_name); f2_name = NULL; } } ret = process_boundaries_insert(ret, boundary); l = g_list_next(l); if (f) { fclose(f); } if (fu) { if (boundary->country) { //osm_warning("relation", item_bin_get_relationid(boundary->ib), 0, "Broken country polygon '%s'\n", boundary->iso2); fprintf(stderr, "*BROKEN* country polygon '%s' relid=%lld\n", boundary->iso2, item_bin_get_relationid(boundary->ib)); } fclose(fu); } if (f1_name) { tempfile_unlink("", f1_name); g_free(f1_name); f1_name = NULL; } } #if 0 printf("hierarchy\n"); #endif // boundaries_list = g_list_sort(boundaries_list, boundary_bbox_compare); // disable sorting, does not seem to do any good // children stuff totally broken!!! #if 0 b_counter_1 = 0; l = boundaries_list; while (l) { b_counter_1++; if ((b_counter_1 % 500) == 0) { fprintf(stderr,"boundaries_f2:B:%lld\n", b_counter_1); } struct boundary *boundary = l->data; ln = l2 = g_list_next(l); while (l2) { struct boundary *boundary2 = l2->data; if (bbox_contains_bbox(&boundary2->r, &boundary->r)) { boundaries_list = g_list_remove(boundaries_list, boundary); boundary2->children = g_list_append(boundary2->children, boundary); break; } l2 = g_list_next(l2); } l = ln; } #endif // children stuff totally broken!!! // -- DEBUG -- // -- DEBUG -- // -- DEBUG -- // dump_hierarchy(boundaries_list,""); // --> prints huge amounts of data!! be careful // -- DEBUG -- // -- DEBUG -- // -- DEBUG -- return boundaries_list; }
void item_bin_add_coord_rect(struct item_bin *ib, struct rect *r) { item_bin_add_coord(ib, &r->l, 1); item_bin_add_coord(ib, &r->h, 1); }
static void close_polygon(struct item_bin *ib, struct coord *from, struct coord *to, int dir, struct rect *bbox, int *edges) { int i,e,dist,fromdist,todist; int full=(bbox->h.x-bbox->l.x+bbox->h.y-bbox->l.y)*2; int corners=0,first_corner=0; struct coord c; if (dir > 0) { fromdist=distance_from_ll(from, bbox); todist=distance_from_ll(to, bbox); } else { fromdist=distance_from_ll(to, bbox); todist=distance_from_ll(from, bbox); } #if 0 fprintf(stderr,"close_polygon fromdist %d todist %d full %d dir %d\n", fromdist, todist, full, dir); #endif if (fromdist > todist) todist+=full; #if 0 fprintf(stderr,"close_polygon corrected fromdist %d todist %d full %d dir %d\n", fromdist, todist, full, dir); #endif for (i = 0 ; i < 8 ; i++) { if (dir > 0) e=i; else e=7-i; switch (e%4) { case 0: c=bbox->l; break; case 1: c.x=bbox->l.x; c.y=bbox->h.y; break; case 2: c=bbox->h; break; case 3: c.x=bbox->h.x; c.y=bbox->l.y; break; } dist=distance_from_ll(&c, bbox); if (e & 4) dist+=full; #if 0 fprintf(stderr,"dist %d %d\n",e,dist); #endif if (dist > fromdist && dist < todist) { item_bin_add_coord(ib, &c, 1); #if 0 fprintf(stderr,"add\n"); #endif } if (dist >= fromdist && dist <= todist) { if (!corners) first_corner=e; corners++; } } while (corners >= 2) { *edges |= 1<<(first_corner%4); first_corner++; corners--; } }
static void tile_collector_process_tile(char *tile, int *tile_data, struct coastline_tile_data *data) { int poly_start_valid,tile_start_valid,exclude,search=0; struct rect bbox; struct coord cn[2],end,poly_start,tile_start; struct geom_poly_segment *first; struct item_bin *ib=(struct item_bin *)buffer; struct item_bin_sink *out=data->sink->priv_data[1]; int dbgl=1; int edges=0,flags; GList *sorted_segments,*curr; #if 0 if (strncmp(tile,"bcdbdcabddddba",7)) return; #endif #if 0 if (strncmp(tile,"bcdbdcaaaaddba",14)) return; #endif #if 0 fprintf(stderr,"tile %s of size %d\n", tile, *tile_data); #endif tile_bbox(tile, &bbox, 0); sorted_segments=geom_poly_segments_sort(tile_data_to_segments(tile_data), geom_poly_segment_type_way_right_side); #if 0 { GList *sort_segments=sorted_segments; int count=0; while (sort_segments) { struct geom_poly_segment *seg=sort_segments->data; struct item_bin *ib=(struct item_bin *)buffer; char *text=g_strdup_printf("segment %d type %d %p %s area "LONGLONG_FMT,count++,seg->type,sort_segments,coord_is_equal(*seg->first, *seg->last) ? "closed":"open",geom_poly_area(seg->first,seg->last-seg->first+1)); item_bin_init(ib, type_rg_segment); item_bin_add_coord(ib, seg->first, seg->last-seg->first+1); item_bin_add_attr_string(ib, attr_debug, text); // fprintf(stderr,"%s\n",text); g_free(text); // item_bin_dump(ib, stderr); item_bin_write_to_sink(ib, out, NULL); sort_segments=g_list_next(sort_segments); } } #endif flags=0; curr=sorted_segments; while (curr) { struct geom_poly_segment *seg=curr->data; switch (seg->type) { case geom_poly_segment_type_way_inner: flags|=1; break; case geom_poly_segment_type_way_outer: flags|=2; break; default: flags|=4; break; } curr=g_list_next(curr); } if (flags == 1) { item_bin_init(ib, type_poly_water_tiled); item_bin_bbox(ib, &bbox); item_bin_write_to_sink(ib, out, NULL); g_hash_table_insert(data->tile_edges, g_strdup(tile), (void *)15); return; } #if 1 end=bbox.l; tile_start_valid=0; poly_start_valid=0; exclude=0; poly_start.x=0; poly_start.y=0; tile_start.x=0; tile_start.y=0; for (;;) { search++; // item_bin_write_debug_point_to_sink(out, &end, "Search %d",search); dbg(dbgl,"searching next polygon from 0x%x 0x%x\n",end.x,end.y); first=find_next(&bbox, sorted_segments, &end, exclude, cn); exclude=1; if (!first) break; if (!tile_start_valid) { tile_start=cn[0]; tile_start_valid=1; } else { if (cn[0].x == tile_start.x && cn[0].y == tile_start.y) { dbg(dbgl,"end of tile reached\n"); break; } } if (first->type == geom_poly_segment_type_none) { end=cn[0]; continue; } poly_start_valid=0; dbg(dbgl,"start of polygon 0x%x 0x%x\n",cn[0].x,cn[0].y); for (;;) { if (!poly_start_valid) { poly_start=cn[0]; poly_start_valid=1; item_bin_init(ib,type_poly_water_tiled); } else { close_polygon(ib, &end, &cn[0], 1, &bbox, &edges); if (cn[0].x == poly_start.x && cn[0].y == poly_start.y) { dbg(dbgl,"poly end reached\n"); item_bin_write_to_sink(ib, out, NULL); end=cn[0]; break; } } if (first->type == geom_poly_segment_type_none) break; item_bin_add_coord(ib, first->first, first->last-first->first+1); first->type=geom_poly_segment_type_none; end=cn[1]; if (distance_from_ll(&end, &bbox) == -1) { dbg(dbgl,"incomplete\n"); break; } first=find_next(&bbox, sorted_segments, &end, 1, cn); dbg(dbgl,"next segment of polygon 0x%x 0x%x\n",cn[0].x,cn[0].y); } if (search > 55) break; } #endif #if 0 { int *end=tile_data+tile_data[0]; int *curr=tile_data+1; while (curr < end) { struct item_bin *ib=(struct item_bin *)curr; // item_bin_dump(ib); ib->type=type_rg_segment; item_bin_write_to_sink(ib, out, NULL); curr+=ib->len+1; #if 0 { struct coord *c[2]; int i; char *s; c[0]=(struct coord *)(ib+1); c[1]=c[0]+ib->clen/2-1; for (i = 0 ; i < 2 ; i++) { s=coord_to_str(c[i]); item_bin_write_debug_point_to_sink(out, c[i], "%s",s); g_free(s); } } #endif } } #endif g_hash_table_insert(data->tile_edges, g_strdup(tile), (void *)edges); #if 0 item_bin_init(ib, type_border_country); item_bin_bbox(ib, &bbox); item_bin_add_attr_string(ib, attr_debug, tile); item_bin_write_to_sink(ib, out, NULL); #endif #if 0 c.x=(bbox.l.x+bbox.h.x)/2; c.y=(bbox.l.y+bbox.h.y)/2; item_bin_write_debug_point_to_sink(out, &c, "%s %d",tile,edges); #endif }
static GList * process_boundaries_finish(GList *boundaries_list) { GList *l,*sl; GList *ret=NULL; l=boundaries_list; while (l) { struct boundary *boundary=l->data; int first=1; FILE *f=NULL,*fu=NULL; if (boundary->country) { char *name=g_strdup_printf("country_%s_poly",boundary->iso2); f=tempfile("",name,1); g_free(name); } boundary->sorted_segments=geom_poly_segments_sort(boundary->segments, geom_poly_segment_type_way_right_side); sl=boundary->sorted_segments; while (sl) { struct geom_poly_segment *gs=sl->data; struct coord *c=gs->first; while (c <= gs->last) { if (first) { boundary->r.l=*c; boundary->r.h=*c; first=0; } else bbox_extend(c, &boundary->r); c++; } if (f) { struct item_bin *ib=tmp_item_bin; item_bin_init(ib, type_selected_line); item_bin_add_coord(ib, gs->first, gs->last-gs->first+1); item_bin_write(ib, f); } if (boundary->country) { if (!coord_is_equal(*gs->first,*gs->last)) { struct item_bin *ib; if (!fu) { char *name=g_strdup_printf("country_%s_broken",boundary->iso2); fu=tempfile("",name,1); g_free(name); } ib=tmp_item_bin; item_bin_init(ib, type_selected_point); item_bin_add_coord(ib, gs->first, 1); item_bin_write(ib, fu); item_bin_init(ib, type_selected_point); item_bin_add_coord(ib, gs->last, 1); item_bin_write(ib, fu); } } sl=g_list_next(sl); } ret=process_boundaries_insert(ret, boundary); l=g_list_next(l); if (f) fclose(f); if (fu) { if (boundary->country) osm_warning("relation",item_bin_get_relationid(boundary->ib),0,"Broken country polygon '%s'\n",boundary->iso2); fclose(fu); } } #if 0 printf("hierarchy\n"); #endif #if 0 boundaries_list=g_list_sort(boundaries_list, boundary_bbox_compare); l=boundaries_list; while (l) { struct boundary *boundary=l->data; GList *l2,*ln; ln=l2=g_list_next(l); while (l2) { struct boundary *boundary2=l2->data; if (bbox_contains_bbox(&boundary2->r, &boundary->r)) { boundaries_list=g_list_remove(boundaries_list, boundary); boundary2->children=g_list_append(boundary2->children, boundary); #if 0 printf("found\n"); #endif break; } l2=g_list_next(l2); } l=ln; } dump_hierarchy(boundaries_list,""); #if 0 printf("hierarchy done\n"); printf("test\n"); test(boundaries_list); #endif #endif return ret; }