7 GList *segments,*sorted_segments;
12 struct boundary_member {
14 enum geom_poly_segment_type role;
15 struct boundary *boundary;
19 boundary_member_hash(gconstpointer key)
21 const struct boundary_member *memb=key;
22 return (memb->wayid >> 32)^(memb->wayid & 0xffffffff);
26 boundary_member_equal(gconstpointer a, gconstpointer b)
28 const struct boundary_member *memba=a;
29 const struct boundary_member *membb=b;
30 return (memba->wayid == membb->wayid);
33 GHashTable *member_hash;
36 osm_tag_name(struct item_bin *ib)
39 while ((tag=item_bin_get_attr(ib, attr_osm_tag, tag))) {
40 if (!strncmp(tag,"name=",5))
47 build_boundaries(FILE *boundaries)
50 GList *boundaries_list=NULL;
52 while ((ib=read_item(boundaries))) {
54 struct boundary *boundary=g_new0(struct boundary, 1);
55 while ((member=item_bin_get_attr(ib, attr_osm_member, member))) {
58 if (sscanf(member,"2:%Ld:%n",&wayid,&read) >= 1) {
59 struct boundary_member *memb=g_new(struct boundary_member, 1);
60 char *role=member+read;
62 memb->boundary=boundary;
63 if (!strcmp(role,"outer"))
64 memb->role=geom_poly_segment_type_way_outer;
65 else if (!strcmp(role,"inner"))
66 memb->role=geom_poly_segment_type_way_inner;
67 else if (!strcmp(role,""))
68 memb->role=geom_poly_segment_type_way_unknown;
70 printf("Unknown role %s\n",role);
71 memb->role=geom_poly_segment_type_none;
73 g_hash_table_insert(member_hash, memb, g_list_append(g_hash_table_lookup(member_hash, memb), memb));
77 boundary->ib=item_bin_dup(ib);
78 boundaries_list=g_list_append(boundaries_list, boundary);
80 return boundaries_list;
84 find_matches(GList *l, struct coord *c)
87 struct boundary *boundary=l->data;
88 if (bbox_contains_coord(&boundary->r, c)) {
89 struct item_bin *ib=boundary->ib;
90 if (geom_poly_segments_point_inside(boundary->sorted_segments,c))
91 printf("%s,",osm_tag_name(ib));
92 find_matches(boundary->children, c);
99 test(GList *boundaries_list)
102 FILE *f=fopen("country_276.bin.unsorted","r");
104 while (ib=read_item(f)) {
105 struct coord *c=(struct coord *)(ib+1);
106 char *name=item_bin_get_attr(ib, attr_town_name, NULL);
108 find_matches(boundaries_list, c);
116 dump_hierarchy(GList *l, char *prefix)
118 char *newprefix=g_alloca(sizeof(char)*(strlen(prefix)+2));
119 strcpy(newprefix, prefix);
120 strcat(newprefix," ");
122 struct boundary *boundary=l->data;
123 printf("%s:%s\n",prefix,osm_tag_name(boundary->ib));
124 dump_hierarchy(boundary->children, newprefix);
130 boundary_bbox_compare(gconstpointer a, gconstpointer b)
132 const struct boundary *boundarya=a;
133 const struct boundary *boundaryb=b;
134 long long areaa=bbox_area(&boundarya->r);
135 long long areab=bbox_area(&boundaryb->r);
144 process_boundaries(FILE *boundaries, FILE *ways)
147 GList *boundaries_list,*l,*sl,*l2,*ln;
149 member_hash=g_hash_table_new_full(boundary_member_hash, boundary_member_equal, NULL, NULL);
150 boundaries_list=build_boundaries(boundaries);
151 while (ib=read_item(ways)) {
152 long long *wayid=item_bin_get_attr(ib, attr_osm_wayid, NULL);
154 GList *l=g_hash_table_lookup(member_hash, wayid);
156 struct boundary_member *memb=l->data;
157 memb->boundary->segments=g_list_prepend(memb->boundary->segments,item_bin_to_poly_segment(ib, memb->role));
165 struct boundary *boundary=l->data;
167 boundary->sorted_segments=geom_poly_segments_sort(boundary->segments, geom_poly_segment_type_way_right_side);
168 sl=boundary->sorted_segments;
170 struct geom_poly_segment *gs=sl->data;
171 struct coord *c=gs->first;
172 while (c <= gs->last) {
178 bbox_extend(c, &boundary->r);
186 printf("hierarchy\n");
187 boundaries_list=g_list_sort(boundaries_list, boundary_bbox_compare);
190 struct boundary *boundary=l->data;
191 ln=l2=g_list_next(l);
193 struct boundary *boundary2=l2->data;
194 if (bbox_contains_bbox(&boundary2->r, &boundary->r)) {
195 boundaries_list=g_list_remove(boundaries_list, boundary);
196 boundary2->children=g_list_append(boundary2->children, boundary);
204 printf("hierarchy done\n");
205 dump_hierarchy(boundaries_list,"");
207 test(boundaries_list);