/[zanavi_public1]/navit/navit/map/mg/town.c
ZANavi

Contents of /navit/navit/map/mg/town.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations) (download)
Fri Oct 28 21:19:04 2011 UTC (12 years, 5 months ago) by zoff99
File MIME type: text/plain
File size: 8537 byte(s)
import files
1 zoff99 2 /**
2     * Navit, a modular navigation system.
3     * Copyright (C) 2005-2008 Navit Team
4     *
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.
8     *
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.
13     *
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.
18     */
19    
20     #include <stdio.h>
21     #include <string.h>
22     #include "debug.h"
23     #include "mg.h"
24    
25    
26    
27     static void
28     town_coord_rewind(void *priv_data)
29     {
30     struct town_priv *twn=priv_data;
31    
32     twn->cidx=0;
33     }
34    
35     static int
36     town_coord_get(void *priv_data, struct coord *c, int count)
37     {
38     struct town_priv *twn=priv_data;
39    
40     if (twn->cidx || count <= 0)
41     return 0;
42     twn->cidx=1;
43     *c=twn->c;
44     return 1;
45     }
46    
47     static void
48     town_attr_rewind(void *priv_data)
49     {
50     struct town_priv *twn=priv_data;
51    
52     twn->aidx=0;
53     twn->attr_next=attr_label;
54     }
55    
56     static int
57     town_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
58     {
59     struct town_priv *twn=priv_data;
60     int len;
61    
62     attr->type=attr_type;
63     switch (attr_type) {
64     case attr_any:
65     while (twn->attr_next != attr_none) {
66     if (town_attr_get(twn, twn->attr_next, attr))
67     return 1;
68     }
69     return 0;
70     case attr_label:
71     attr->u.str=twn->district;
72     twn->attr_next=attr_town_name;
73     if (attr->u.str[0])
74     return 1;
75     attr->u.str=twn->name;
76     return ((attr->u.str && attr->u.str[0]) ? 1:0);
77     case attr_town_name:
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:
82     case attr_postal:
83     strncpy(twn->postal, twn->postal_code1, 32);
84     attr->u.str=twn->postal;
85     len=mg_country_postal_len(twn->country);
86     if (!len)
87     len=31;
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;
101     return 1;
102     case 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;
106     return 1;
107     default:
108     dbg(1, "Don't know about attribute %d[%04X]=%s yet\n",
109     attr_type, attr_type, attr_to_name(attr_type));
110     return 0;
111     }
112     return 1;
113     }
114    
115     static struct item_methods town_meth = {
116     town_coord_rewind,
117     town_coord_get,
118     town_attr_rewind,
119     town_attr_get,
120     };
121    
122     static void
123     town_get_data(struct town_priv *twn, unsigned char **p)
124     {
125     twn->id=get_u32_unal(p);
126     twn->c.x=get_u32_unal(p);
127     twn->c.y=get_u32_unal(p);
128     twn->name=get_string(p);
129     twn->district=get_string(p);
130     twn->postal_code1=get_string(p);
131     twn->order=get_u8(p); /* 1-15 (19) */
132     twn->country=get_u16_unal(p);
133     twn->type=get_u8(p);
134     twn->unknown2=get_u32_unal(p);
135     twn->size=get_u8(p);
136     twn->street_assoc=get_u32_unal(p);
137     twn->unknown3=get_u8(p);
138     twn->postal_code2=get_string(p);
139     twn->unknown4=get_u32_unal(p);
140     #if 0
141     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);
142     #endif
143     }
144     /*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 */
145     static unsigned char limit[]={0,1,2,2,4,6,8,10,11,13,14,14,14,20,20,20,20,20,20};
146    
147     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};
148     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     int
150     town_get(struct map_rect_priv *mr, struct town_priv *twn, struct item *item)
151     {
152     int size;
153     for (;;) {
154     if (mr->b.p >= mr->b.end)
155     return 0;
156     town_get_data(twn, &mr->b.p);
157     twn->cidx=0;
158     twn->aidx=0;
159     twn->attr_next=attr_label;
160     if (! mr->cur_sel || (twn->order <= limit[mr->cur_sel->order] && coord_rect_contains(&mr->cur_sel->u.c_rect,&twn->c))) {
161     switch(twn->type) {
162     case 1:
163     size=twn->size;
164     if (size >= sizeof(town_item)/sizeof(enum item_type))
165     size=sizeof(town_item)/sizeof(enum item_type)-1;
166     item->type=town_item[size];
167     break;
168     case 3:
169     size=twn->size;
170     if (size == 6 && twn->order < 14)
171     size++;
172     if (size == 5 && twn->order < 14)
173     size+=2;
174     if (size >= sizeof(district_item)/sizeof(enum item_type))
175     size=sizeof(district_item)/sizeof(enum item_type)-1;
176     item->type=district_item[size];
177     break;
178     case 4:
179     item->type=type_port_label;
180     break;
181     case 9:
182     item->type=type_highway_exit_label;
183     break;
184     default:
185     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);
186     item->type=type_town_label;
187     }
188     if (map_selection_contains_item(mr->cur_sel, 0, item->type)) {
189     item->id_hi=twn->country | (mr->current_file << 16);
190     item->id_lo=twn->id;
191     item->priv_data=twn;
192     item->meth=&town_meth;
193     return 1;
194     }
195     }
196     }
197     }
198    
199     int
200     town_get_byid(struct map_rect_priv *mr, struct town_priv *twn, int id_hi, int id_lo, struct item *item)
201     {
202     int country=id_hi & 0xffff;
203     int res;
204     if (!tree_search_hv(mr->m->dirname, "town", (id_lo >> 8) | (country << 24), id_lo & 0xff, &res))
205     return 0;
206     block_get_byindex(mr->m->file[mr->current_file], res >> 16, &mr->b);
207     mr->b.p=mr->b.block_start+(res & 0xffff);
208     return town_get(mr, twn, item);
209     }
210    
211     static int
212     town_search_compare(unsigned char **p, struct map_rect_priv *mr)
213     {
214     int country, d;
215     char *name;
216    
217     if (mr->search_type == attr_town_postal) {
218     mr->search_blk_count=1;
219     mr->search_blk_off=(struct block_offset *)(*p);
220     *p+=4;
221     name=get_string(p);
222     d=0;
223     } else {
224     country=get_u16_unal(p);
225     dbg(1,"country 0x%x ", country);
226     name=get_string(p);
227     dbg(1,"name '%s' ",name);
228     mr->search_blk_count=get_u32_unal(p);
229     mr->search_blk_off=(struct block_offset *)(*p);
230     dbg(1,"len %d ", mr->search_blk_count);
231     (*p)+=mr->search_blk_count*4;
232     d=mr->search_country-country;
233     }
234     if (!d) {
235     if (mr->search_partial)
236     d=strncasecmp(mr->search_str, name, strlen(mr->search_str));
237     else
238     d=strcasecmp(mr->search_str, name);
239     }
240     dbg(1,"%d \n",d);
241     return d;
242    
243     }
244    
245    
246    
247     struct item *
248     town_search_get_item(struct map_rect_priv *mr)
249     {
250     int dir=1,leaf;
251    
252     if (! mr->search_blk_count) {
253     dbg(1,"partial %d 0x%x '%s' ***\n", mr->search_partial, mr->search_country, mr->search_str);
254     if (! mr->search_linear) {
255     while ((leaf=tree_search_next(&mr->ts, &mr->search_p, dir)) != -1) {
256     dir=town_search_compare(&mr->search_p, mr);
257     if (! dir) {
258     mr->search_linear=1;
259     mr->search_p=NULL;
260     break;
261     }
262     }
263     if (! mr->search_linear) {
264     dbg(1,"not found\n");
265     return NULL;
266     }
267     }
268     if (! tree_search_next_lin(&mr->ts, &mr->search_p)) {
269     dbg(1,"linear not found\n");
270     return NULL;
271     }
272     if (town_search_compare(&mr->search_p, mr)) {
273     dbg(1,"no match\n");
274     return NULL;
275     }
276     dbg(1,"found %d blocks\n",mr->search_blk_count);
277     }
278     if (! mr->search_blk_count)
279     return NULL;
280     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));
281     block_get_byindex(mr->m->file[mr->current_file], block_offset_get_block(mr->search_blk_off), &mr->b);
282     mr->b.p=mr->b.block_start+block_offset_get_offset(mr->search_blk_off);
283     town_get(mr, &mr->town, &mr->item);
284     mr->search_blk_off++;
285     mr->search_blk_count--;
286     return &mr->item;
287     }

   
Visit the ZANavi Wiki