/[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 - (show 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 /**
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