2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2008 Navit Team
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
28 town_coord_rewind(void *priv_data)
30 struct town_priv *twn=priv_data;
36 town_coord_get(void *priv_data, struct coord *c, int count)
38 struct town_priv *twn=priv_data;
40 if (twn->cidx || count <= 0)
48 town_attr_rewind(void *priv_data)
50 struct town_priv *twn=priv_data;
53 twn->attr_next=attr_label;
57 town_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
59 struct town_priv *twn=priv_data;
65 while (twn->attr_next != attr_none) {
66 if (town_attr_get(twn, twn->attr_next, attr))
71 attr->u.str=twn->district;
72 twn->attr_next=attr_town_name;
75 attr->u.str=twn->name;
76 return ((attr->u.str && attr->u.str[0]) ? 1:0);
78 attr->u.str=twn->name;
79 twn->attr_next=attr_town_postal;
80 return ((attr->u.str && attr->u.str[0]) ? 1:0);
81 case attr_town_postal:
83 strncpy(twn->postal, twn->postal_code1, 32);
84 attr->u.str=twn->postal;
85 len=mg_country_postal_len(twn->country);
88 twn->postal[len]='\0';
89 twn->attr_next=attr_district_name;
90 return ((attr->u.str && attr->u.str[0]) ? 1:0);
91 case attr_district_name:
92 attr->u.str=twn->district;
93 twn->attr_next=attr_debug;
94 return ((attr->u.str && attr->u.str[0]) ? 1:0);
95 case attr_town_streets_item:
96 twn->town_attr_item.type=type_town_streets;
97 twn->town_attr_item.id_hi=twn->country | (file_town_twn << 16) | 0x10000000;
98 twn->town_attr_item.id_lo=twn->street_assoc;
99 attr->u.item=&twn->town_attr_item;
100 twn->attr_next=attr_debug;
103 sprintf(twn->debug, "order %d\nsize %d\nstreet_assoc 0x%x", twn->order, twn->size, twn->street_assoc);
104 attr->u.str=twn->debug;
105 twn->attr_next=attr_none;
114 static struct item_methods town_meth = {
122 town_get_data(struct town_priv *twn, unsigned char **p)
124 twn->id=get_u32_unal(p);
125 twn->c.x=get_u32_unal(p);
126 twn->c.y=get_u32_unal(p);
127 twn->name=get_string(p);
128 twn->district=get_string(p);
129 twn->postal_code1=get_string(p);
130 twn->order=get_u8(p); /* 1-15 (19) */
131 twn->country=get_u16_unal(p);
133 twn->unknown2=get_u32_unal(p);
135 twn->street_assoc=get_u32_unal(p);
136 twn->unknown3=get_u8(p);
137 twn->postal_code2=get_string(p);
138 twn->unknown4=get_u32_unal(p);
140 printf("%s\t%s\t%s\t%d\t%d\t%d\n",twn->name,twn->district,twn->postal_code1,twn->order, twn->country, twn->type);
143 /*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 */
144 static unsigned char limit[]={0,1,2,2,4,6,8,10,11,13,14,14,14,20,20,20,20,20,20};
146 static enum item_type town_item[]={type_town_label_5e1, type_town_label_1e2, type_town_label_2e2, type_town_label_5e2, type_town_label_1e3, type_town_label_1e3, type_town_label_2e3, type_town_label_5e3, type_town_label_1e4, type_town_label_2e4, type_town_label_5e4, type_town_label_1e5, type_town_label_1e5, type_town_label_2e5, type_town_label_5e5, type_town_label_1e6, type_town_label_2e6};
147 static enum item_type district_item[]={type_district_label_5e1, type_district_label_1e2, type_district_label_2e2, type_district_label_5e2, type_district_label_1e3, type_district_label_1e3, type_district_label_2e3, type_district_label_5e3, type_district_label_1e4, type_district_label_2e4, type_district_label_5e4, type_district_label_1e5, type_district_label_1e5, type_district_label_2e5, type_district_label_5e5, type_district_label_1e6, type_district_label_2e6};
149 town_get(struct map_rect_priv *mr, struct town_priv *twn, struct item *item)
153 if (mr->b.p >= mr->b.end)
155 town_get_data(twn, &mr->b.p);
158 twn->attr_next=attr_label;
159 if (! mr->cur_sel || (twn->order <= limit[mr->cur_sel->order] && coord_rect_contains(&mr->cur_sel->u.c_rect,&twn->c))) {
163 if (size >= sizeof(town_item)/sizeof(enum item_type))
164 size=sizeof(town_item)/sizeof(enum item_type)-1;
165 item->type=town_item[size];
169 if (size == 6 && twn->order < 14)
171 if (size == 5 && twn->order < 14)
173 if (size >= sizeof(district_item)/sizeof(enum item_type))
174 size=sizeof(district_item)/sizeof(enum item_type)-1;
175 item->type=district_item[size];
178 item->type=type_port_label;
181 item->type=type_highway_exit_label;
184 printf("unknown town type 0x%x '%s' '%s' 0x%x,0x%x\n", twn->type, twn->name, twn->district, twn->c.x, twn->c.y);
185 item->type=type_town_label;
187 if (map_selection_contains_item(mr->cur_sel, 0, item->type)) {
188 item->id_hi=twn->country | (mr->current_file << 16);
191 item->meth=&town_meth;
199 town_get_byid(struct map_rect_priv *mr, struct town_priv *twn, int id_hi, int id_lo, struct item *item)
201 int country=id_hi & 0xffff;
203 if (!tree_search_hv(mr->m->dirname, "town", (id_lo >> 8) | (country << 24), id_lo & 0xff, &res))
205 block_get_byindex(mr->m->file[mr->current_file], res >> 16, &mr->b);
206 mr->b.p=mr->b.block_start+(res & 0xffff);
207 return town_get(mr, twn, item);
211 town_search_compare(unsigned char **p, struct map_rect_priv *mr)
216 if (mr->search_type == attr_town_postal) {
217 mr->search_blk_count=1;
218 mr->search_blk_off=(struct block_offset *)(*p);
223 country=get_u16_unal(p);
224 dbg(1,"country 0x%x ", country);
226 dbg(1,"name '%s' ",name);
227 mr->search_blk_count=get_u32_unal(p);
228 mr->search_blk_off=(struct block_offset *)(*p);
229 dbg(1,"len %d ", mr->search_blk_count);
230 (*p)+=mr->search_blk_count*4;
231 d=mr->search_country-country;
234 if (mr->search_partial)
235 d=strncasecmp(mr->search_str, name, strlen(mr->search_str));
237 d=strcasecmp(mr->search_str, name);
247 town_search_get_item(struct map_rect_priv *mr)
251 if (! mr->search_blk_count) {
252 dbg(1,"partial %d 0x%x '%s' ***\n", mr->search_partial, mr->search_country, mr->search_str);
253 if (! mr->search_linear) {
254 while ((leaf=tree_search_next(&mr->ts, &mr->search_p, dir)) != -1) {
255 dir=town_search_compare(&mr->search_p, mr);
262 if (! mr->search_linear) {
263 dbg(1,"not found\n");
267 if (! tree_search_next_lin(&mr->ts, &mr->search_p)) {
268 dbg(1,"linear not found\n");
271 if (town_search_compare(&mr->search_p, mr)) {
275 dbg(1,"found %d blocks\n",mr->search_blk_count);
277 if (! mr->search_blk_count)
279 dbg(1,"block 0x%x offset 0x%x\n", block_offset_get_block(mr->search_blk_off), block_offset_get_offset(mr->search_blk_off));
280 block_get_byindex(mr->m->file[mr->current_file], block_offset_get_block(mr->search_blk_off), &mr->b);
281 mr->b.p=mr->b.block_start+block_offset_get_offset(mr->search_blk_off);
282 town_get(mr, &mr->town, &mr->item);
283 mr->search_blk_off++;
284 mr->search_blk_count--;