/[zanavi_public1]/navit/navit/maptool/itembin.c
ZANavi

Contents of /navit/navit/maptool/itembin.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (hide annotations) (download)
Fri Oct 28 21:39:42 2011 UTC (12 years, 5 months ago) by zoff99
File MIME type: text/plain
File size: 12428 byte(s)
import
1 zoff99 8 /**
2     * Navit, a modular navigation system.
3     * Copyright (C) 2005-2011 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 <string.h>
21     #include <stdlib.h>
22     #include "maptool.h"
23     #include "linguistics.h"
24     #include "file.h"
25     #include "debug.h"
26    
27    
28    
29     int
30     item_bin_read(struct item_bin *ib, FILE *in)
31     {
32     if (fread(ib, 4, 1, in) == 0)
33     return 0;
34     if (!ib->len)
35     return 1;
36     if (fread((unsigned char *)ib+4, ib->len*4, 1, in))
37     return 2;
38     return 0;
39     }
40    
41     void
42     item_bin_set_type(struct item_bin *ib, enum item_type type)
43     {
44     ib->type=type;
45     }
46    
47     void
48     item_bin_init(struct item_bin *ib, enum item_type type)
49     {
50     ib->clen=0;
51     ib->len=2;
52     item_bin_set_type(ib, type);
53     }
54    
55    
56     void
57     item_bin_add_coord(struct item_bin *ib, struct coord *c, int count)
58     {
59     struct coord *c2=(struct coord *)(ib+1);
60     c2+=ib->clen/2;
61     memcpy(c2, c, count*sizeof(struct coord));
62     ib->clen+=count*2;
63     ib->len+=count*2;
64     }
65    
66     void
67     item_bin_add_coord_reverse(struct item_bin *ib, struct coord *c, int count)
68     {
69     int i;
70     for (i = count-1 ; i >= 0 ; i--)
71     item_bin_add_coord(ib, &c[i], 1);
72     }
73    
74     void
75     item_bin_bbox(struct item_bin *ib, struct rect *r)
76     {
77     struct coord c;
78     item_bin_add_coord(ib, &r->l, 1);
79     c.x=r->h.x;
80     c.y=r->l.y;
81     item_bin_add_coord(ib, &c, 1);
82     item_bin_add_coord(ib, &r->h, 1);
83     c.x=r->l.x;
84     c.y=r->h.y;
85     item_bin_add_coord(ib, &c, 1);
86     item_bin_add_coord(ib, &r->l, 1);
87     }
88    
89     void
90     item_bin_copy_coord(struct item_bin *ib, struct item_bin *from, int dir)
91     {
92     struct coord *c=(struct coord *)(from+1);
93     int i,count=from->clen/2;
94     if (dir >= 0) {
95     item_bin_add_coord(ib, c, count);
96     return;
97     }
98     for (i = 1 ; i <= count ; i++)
99     item_bin_add_coord(ib, &c[count-i], 1);
100     }
101    
102     void
103     item_bin_add_coord_rect(struct item_bin *ib, struct rect *r)
104     {
105     item_bin_add_coord(ib, &r->l, 1);
106     item_bin_add_coord(ib, &r->h, 1);
107     }
108    
109     int
110     attr_bin_write_data(struct attr_bin *ab, enum attr_type type, void *data, int size)
111     {
112     int pad=(4-(size%4))%4;
113     ab->type=type;
114     memcpy(ab+1, data, size);
115     memset((unsigned char *)(ab+1)+size, 0, pad);
116     ab->len=(size+pad)/4+1;
117     return ab->len+1;
118     }
119    
120     int
121     attr_bin_write_attr(struct attr_bin *ab, struct attr *attr)
122     {
123     return attr_bin_write_data(ab, attr->type, attr_data_get(attr), attr_data_size(attr));
124     }
125    
126     void
127     item_bin_add_attr_data(struct item_bin *ib, enum attr_type type, void *data, int size)
128     {
129     struct attr_bin *ab=(struct attr_bin *)((int *)ib+ib->len+1);
130     ib->len+=attr_bin_write_data(ab, type, data, size);
131     }
132    
133     void
134     item_bin_add_attr(struct item_bin *ib, struct attr *attr)
135     {
136     struct attr_bin *ab=(struct attr_bin *)((int *)ib+ib->len+1);
137     if (ATTR_IS_GROUP(attr->type)) {
138     int i=0;
139     int *abptr;
140     ab->type=attr->type;
141     ab->len=1;
142     abptr=(int *)(ab+1);
143     while (attr->u.attrs[i].type) {
144     int size=attr_bin_write_attr((struct attr_bin *)abptr, &attr->u.attrs[i]);
145     ab->len+=size;
146     abptr+=size;
147     i++;
148     }
149     ib->len+=ab->len+1;
150    
151     } else
152     ib->len+=attr_bin_write_attr(ab, attr);
153    
154     }
155    
156     void
157     item_bin_add_attr_int(struct item_bin *ib, enum attr_type type, int val)
158     {
159     struct attr attr;
160     attr.type=type;
161     attr.u.num=val;
162     item_bin_add_attr(ib, &attr);
163     }
164    
165     void *
166     item_bin_get_attr(struct item_bin *ib, enum attr_type type, void *last)
167     {
168     unsigned char *s=(unsigned char *)ib;
169     unsigned char *e=s+(ib->len+1)*4;
170     s+=sizeof(struct item_bin)+ib->clen*4;
171     while (s < e) {
172     struct attr_bin *ab=(struct attr_bin *)s;
173     s+=(ab->len+1)*4;
174     if (ab->type == type && (void *)(ab+1) > last) {
175     return (ab+1);
176     }
177     }
178     return NULL;
179     }
180    
181     struct attr_bin *
182     item_bin_get_attr_bin_last(struct item_bin *ib)
183     {
184     struct attr_bin *ab=NULL;
185     unsigned char *s=(unsigned char *)ib;
186     unsigned char *e=s+(ib->len+1)*4;
187     s+=sizeof(struct item_bin)+ib->clen*4;
188     while (s < e) {
189     ab=(struct attr_bin *)s;
190     s+=(ab->len+1)*4;
191     }
192     return ab;
193     }
194    
195     void
196     item_bin_add_attr_longlong(struct item_bin *ib, enum attr_type type, long long val)
197     {
198     struct attr attr;
199     attr.type=type;
200     attr.u.num64=&val;
201     item_bin_add_attr(ib, &attr);
202     }
203    
204     void
205     item_bin_add_attr_string(struct item_bin *ib, enum attr_type type, char *str)
206     {
207     struct attr attr;
208     if (! str)
209     return;
210     attr.type=type;
211     attr.u.str=str;
212     item_bin_add_attr(ib, &attr);
213     }
214    
215     void
216     item_bin_add_attr_range(struct item_bin *ib, enum attr_type type, short min, short max)
217     {
218     struct attr attr;
219     attr.type=type;
220     attr.u.range.min=min;
221     attr.u.range.max=max;
222     item_bin_add_attr(ib, &attr);
223     }
224    
225     void
226     item_bin_write(struct item_bin *ib, FILE *out)
227     {
228     fwrite(ib, (ib->len+1)*4, 1, out);
229     }
230    
231     struct item_bin *
232     item_bin_dup(struct item_bin *ib)
233     {
234     int len=(ib->len+1)*4;
235     struct item_bin *ret=g_malloc(len);
236     memcpy(ret, ib, len);
237    
238     return ret;
239     }
240    
241     void
242     item_bin_write_range(struct item_bin *ib, FILE *out, int min, int max)
243     {
244     struct range r;
245    
246     r.min=min;
247     r.max=max;
248     fwrite(&r, sizeof(r), 1, out);
249     item_bin_write(ib, out);
250     }
251    
252    
253     void
254     item_bin_write_clipped(struct item_bin *ib, struct tile_parameter *param, struct item_bin_sink *out)
255     {
256     struct tile_data tile_data;
257     int i;
258     bbox((struct coord *)(ib+1), ib->clen/2, &tile_data.item_bbox);
259     tile_data.buffer[0]='\0';
260     tile_data.tile_depth=tile(&tile_data.item_bbox, NULL, tile_data.buffer, param->max, param->overlap, &tile_data.tile_bbox);
261     if (tile_data.tile_depth == param->max || tile_data.tile_depth >= param->min) {
262     item_bin_write_to_sink(ib, out, &tile_data);
263     return;
264     }
265     for (i = 0 ; i < 4 ; i++) {
266     struct rect clip_rect;
267     tile_data.buffer[tile_data.tile_depth]='a'+i;
268     tile_data.buffer[tile_data.tile_depth+1]='\0';
269     tile_bbox(tile_data.buffer, &clip_rect, param->overlap);
270     if (ib->type < type_area)
271     clip_line(ib, &clip_rect, param, out);
272     else
273     clip_polygon(ib, &clip_rect, param, out);
274     }
275     }
276    
277     static char *
278     coord_to_str(struct coord *c)
279     {
280     int x=c->x;
281     int y=c->y;
282     char *sx="";
283     char *sy="";
284     if (x < 0) {
285     sx="-";
286     x=-x;
287     }
288     if (y < 0) {
289     sy="-";
290     y=-y;
291     }
292     return g_strdup_printf("%s0x%x %s0x%x",sx,x,sy,y);
293     }
294    
295     static void
296     dump_coord(struct coord *c, FILE *out)
297     {
298     char *str=coord_to_str(c);
299     fprintf(out,"%s",str);
300     g_free(str);
301     }
302    
303    
304     void
305     item_bin_dump(struct item_bin *ib, FILE *out)
306     {
307     struct coord *c;
308     struct attr_bin *a;
309     struct attr attr;
310     int *attr_start;
311     int *attr_end;
312     int i;
313     char *str;
314    
315     c=(struct coord *)(ib+1);
316     if (ib->type < type_line) {
317     dump_coord(c,out);
318     fprintf(out, " ");
319     }
320     attr_start=(int *)(ib+1)+ib->clen;
321     attr_end=(int *)ib+ib->len+1;
322     fprintf(out,"type=%s", item_to_name(ib->type));
323     while (attr_start < attr_end) {
324     a=(struct attr_bin *)(attr_start);
325     attr_start+=a->len+1;
326     attr.type=a->type;
327     attr_data_set(&attr, (a+1));
328     str=attr_to_text(&attr, NULL, 1);
329     fprintf(out," %s=\"%s\"", attr_to_name(a->type), str);
330     g_free(str);
331     }
332     fprintf(out," debug=\"length=%d\"", ib->len);
333     fprintf(out,"\n");
334     if (ib->type >= type_line) {
335     for (i = 0 ; i < ib->clen/2 ; i++) {
336     dump_coord(c+i,out);
337     fprintf(out,"\n");
338     }
339     }
340     }
341    
342     void
343     dump_itembin(struct item_bin *ib)
344     {
345     item_bin_dump(ib, stdout);
346     }
347    
348     struct population_table {
349     enum item_type type;
350     int population;
351     };
352    
353     static struct population_table town_population[] = {
354     {type_town_label_0e0,0},
355     {type_town_label_1e0,1},
356     {type_town_label_2e0,2},
357     {type_town_label_5e0,5},
358     {type_town_label_1e1,10},
359     {type_town_label_2e1,20},
360     {type_town_label_5e1,50},
361     {type_town_label_1e2,100},
362     {type_town_label_2e2,200},
363     {type_town_label_5e2,500},
364     {type_town_label_1e3,1000},
365     {type_town_label_2e3,2000},
366     {type_town_label_5e3,5000},
367     {type_town_label_1e4,10000},
368     {type_town_label_2e4,20000},
369     {type_town_label_5e4,50000},
370     {type_town_label_1e5,100000},
371     {type_town_label_2e5,200000},
372     {type_town_label_5e5,500000},
373     {type_town_label_1e6,1000000},
374     {type_town_label_2e6,2000000},
375     {type_town_label_5e6,5000000},
376     {type_town_label_1e7,10000000},
377     };
378    
379     static struct population_table district_population[] = {
380     {type_district_label_0e0,0},
381     {type_district_label_1e0,1},
382     {type_district_label_2e0,2},
383     {type_district_label_5e0,5},
384     {type_district_label_1e1,10},
385     {type_district_label_2e1,20},
386     {type_district_label_5e1,50},
387     {type_district_label_1e2,100},
388     {type_district_label_2e2,200},
389     {type_district_label_5e2,500},
390     {type_district_label_1e3,1000},
391     {type_district_label_2e3,2000},
392     {type_district_label_5e3,5000},
393     {type_district_label_1e4,10000},
394     {type_district_label_2e4,20000},
395     {type_district_label_5e4,50000},
396     {type_district_label_1e5,100000},
397     {type_district_label_2e5,200000},
398     {type_district_label_5e5,500000},
399     {type_district_label_1e6,1000000},
400     {type_district_label_2e6,2000000},
401     {type_district_label_5e6,5000000},
402     {type_district_label_1e7,10000000},
403     };
404    
405     void
406     item_bin_set_type_by_population(struct item_bin *ib, int population)
407     {
408     struct population_table *table;
409     int i,count;
410    
411     if (population < 0)
412     population=0;
413     if (item_is_district(*ib)) {
414     table=district_population;
415     count=sizeof(district_population)/sizeof(district_population[0]);
416     } else {
417     table=town_population;
418     count=sizeof(town_population)/sizeof(town_population[0]);
419     }
420     for (i = 0 ; i < count ; i++) {
421     if (population < table[i].population)
422     break;
423     }
424     item_bin_set_type(ib, table[i-1].type);
425     }
426    
427    
428     void
429     item_bin_write_match(struct item_bin *ib, enum attr_type type, enum attr_type match, FILE *out)
430     {
431     char *word=item_bin_get_attr(ib, type, NULL);
432     int i,words=0,len=ib->len;
433     if (!word)
434     return;
435     do {
436     if (linguistics_search(word)) {
437     for (i = 0 ; i < 3 ; i++) {
438     char *str=linguistics_expand_special(word, i);
439     if (str) {
440     ib->len=len;
441     if (i || words)
442     item_bin_add_attr_string(ib, match, str);
443     item_bin_write(ib, out);
444     g_free(str);
445     }
446     }
447     words++;
448     }
449     word=linguistics_next_word(word);
450     } while (word);
451     }
452    
453     static int
454     item_bin_sort_compare(const void *p1, const void *p2)
455     {
456     struct item_bin *ib1=*((struct item_bin **)p1),*ib2=*((struct item_bin **)p2);
457     struct attr_bin *attr1,*attr2;
458     char *s1,*s2;
459     int ret;
460     #if 0
461     dbg_assert(ib1->clen==2);
462     dbg_assert(ib2->clen==2);
463     attr1=(struct attr_bin *)((int *)(ib1+1)+ib1->clen);
464     attr2=(struct attr_bin *)((int *)(ib2+1)+ib1->clen);
465     #else
466     attr1=item_bin_get_attr_bin_last(ib1);
467     attr2=item_bin_get_attr_bin_last(ib2);
468     #endif
469     #if 0
470     dbg_assert(attr1->type == attr_town_name || attr1->type == attr_town_name_match);
471     dbg_assert(attr2->type == attr_town_name || attr2->type == attr_town_name_match);
472     #endif
473     s1=(char *)(attr1+1);
474     s2=(char *)(attr2+1);
475     if (attr1->type == attr_house_number && attr2->type == attr_house_number) {
476     ret=atoi(s1)-atoi(s2);
477     if (ret)
478     return ret;
479     }
480     ret=strcmp(s1, s2);
481     if (!ret) {
482     int match1=0,match2=0;
483     match1=(attr1->type == attr_town_name_match || attr1->type == attr_district_name_match);
484     match2=(attr2->type == attr_town_name_match || attr2->type == attr_district_name_match);
485     ret=match1-match2;
486     }
487     #if 0
488     fprintf(stderr,"sort_countries_compare p1=%p p2=%p %s %s\n",p1,p2,s1,s2);
489     #endif
490     return ret;
491     }
492    
493     int
494     item_bin_sort_file(char *in_file, char *out_file, struct rect *r, int *size)
495     {
496     int j,k,count,rc=0;
497     struct coord *c;
498     struct item_bin *ib;
499     FILE *f;
500     unsigned char *p,**idx,*buffer;
501     if (file_get_contents(in_file, &buffer, size)) {
502     ib=(struct item_bin *)buffer;
503     p=buffer;
504     count=0;
505     while (p < buffer+*size) {
506     count++;
507     p+=(*((int *)p)+1)*4;
508     }
509     idx=malloc(count*sizeof(void *));
510     dbg_assert(idx != NULL);
511     p=buffer;
512     for (j = 0 ; j < count ; j++) {
513     idx[j]=p;
514     p+=(*((int *)p)+1)*4;
515     }
516     qsort(idx, count, sizeof(void *), item_bin_sort_compare);
517     f=fopen(out_file,"wb");
518     for (j = 0 ; j < count ; j++) {
519     ib=(struct item_bin *)(idx[j]);
520     c=(struct coord *)(ib+1);
521     fwrite(ib, (ib->len+1)*4, 1, f);
522     if (r) {
523     for (k = 0 ; k < ib->clen/2 ; k++) {
524     if (rc)
525     bbox_extend(&c[k], r);
526     else {
527     r->l=c[k];
528     r->h=c[k];
529     }
530     rc++;
531     }
532     }
533     }
534     fclose(f);
535     return 1;
536     }
537     return 0;
538     }

   
Visit the ZANavi Wiki