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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

   
Visit the ZANavi Wiki