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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Mon Feb 4 17:41:59 2013 UTC (11 years, 1 month ago) by zoff99
File MIME type: text/plain
File size: 18215 byte(s)
new map version, lots of fixes and experimental new features
1 /**
2 * ZANavi, Zoff Android Navigation system.
3 * Copyright (C) 2011-2012 Zoff <zoff@zoff.cc>
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 /**
21 * Navit, a modular navigation system.
22 * Copyright (C) 2005-2011 Navit Team
23 *
24 * This program is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU General Public License
26 * version 2 as published by the Free Software Foundation.
27 *
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
32 *
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the
35 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
36 * Boston, MA 02110-1301, USA.
37 */
38
39 #define _FILE_OFFSET_BITS 64
40 #define _LARGEFILE_SOURCE
41 #define _LARGEFILE64_SOURCE
42 #include <string.h>
43 #include <stdlib.h>
44 #include "maptool.h"
45 #include "linguistics.h"
46 #include "file.h"
47 #include "debug.h"
48
49 int item_bin_read(struct item_bin *ib, FILE *in)
50 {
51 if (fread(ib, 4, 1, in) == 0)
52 return 0;
53 if (!ib->len)
54 return 1;
55 if (fread((unsigned char *) ib + 4, ib->len * 4, 1, in))
56 return 2;
57 return 0;
58 }
59
60 void item_bin_set_type(struct item_bin *ib, enum item_type type)
61 {
62 ib->type = type;
63 }
64
65 void item_bin_init(struct item_bin *ib, enum item_type type)
66 {
67 ib->clen = 0;
68 ib->len = 2;
69 item_bin_set_type(ib, type);
70 }
71
72 void item_bin_add_coord(struct item_bin *ib, struct coord *c, int count)
73 {
74 struct coord *c2 = (struct coord *) (ib + 1);
75 c2 += ib->clen / 2;
76 memcpy(c2, c, count * sizeof(struct coord));
77 ib->clen += count * 2;
78 ib->len += count * 2;
79 }
80
81 void item_bin_add_coord_reverse(struct item_bin *ib, struct coord *c, int count)
82 {
83 int i;
84 for (i = count - 1; i >= 0; i--)
85 {
86 item_bin_add_coord(ib, &c[i], 1);
87 }
88 }
89
90 void item_bin_bbox(struct item_bin *ib, struct rect *r)
91 {
92 struct coord c;
93 item_bin_add_coord(ib, &r->l, 1);
94 c.x = r->h.x;
95 c.y = r->l.y;
96 item_bin_add_coord(ib, &c, 1);
97 item_bin_add_coord(ib, &r->h, 1);
98 c.x = r->l.x;
99 c.y = r->h.y;
100 item_bin_add_coord(ib, &c, 1);
101 item_bin_add_coord(ib, &r->l, 1);
102 }
103
104 void item_bin_copy_coord(struct item_bin *ib, struct item_bin *from, int dir)
105 {
106 struct coord *c = (struct coord *) (from + 1);
107 int i, count = from->clen / 2;
108 if (dir >= 0)
109 {
110 item_bin_add_coord(ib, c, count);
111 return;
112 }
113 for (i = 1; i <= count; i++)
114 {
115 item_bin_add_coord(ib, &c[count - i], 1);
116 }
117 }
118
119 void item_bin_add_coord_rect(struct item_bin *ib, struct rect *r)
120 {
121 item_bin_add_coord(ib, &r->l, 1);
122 item_bin_add_coord(ib, &r->h, 1);
123 }
124
125 int attr_bin_write_data(struct attr_bin *ab, enum attr_type type, void *data, int size)
126 {
127 int pad = (4 - (size % 4)) % 4;
128 ab->type = type;
129 memcpy(ab + 1, data, size);
130 memset((unsigned char *) (ab + 1) + size, 0, pad);
131 ab->len = (size + pad) / 4 + 1;
132 return ab->len + 1;
133 }
134
135 int attr_bin_write_attr(struct attr_bin *ab, struct attr *attr)
136 {
137 return attr_bin_write_data(ab, attr->type, attr_data_get(attr), attr_data_size(attr));
138 }
139
140 void item_bin_add_attr_data(struct item_bin *ib, enum attr_type type, void *data, int size)
141 {
142 struct attr_bin *ab = (struct attr_bin *) ((int *) ib + ib->len + 1);
143 ib->len += attr_bin_write_data(ab, type, data, size);
144 }
145
146 void item_bin_add_attr(struct item_bin *ib, struct attr *attr)
147 {
148 struct attr_bin *ab = (struct attr_bin *) ((int *) ib + ib->len + 1);
149 if (ATTR_IS_GROUP(attr->type))
150 {
151 int i = 0;
152 int *abptr;
153 ab->type = attr->type;
154 ab->len = 1;
155 abptr = (int *) (ab + 1);
156 while (attr->u.attrs[i].type)
157 {
158 int size = attr_bin_write_attr((struct attr_bin *) abptr, &attr->u.attrs[i]);
159 ab->len += size;
160 abptr += size;
161 i++;
162 }
163 ib->len += ab->len + 1;
164
165 }
166 else
167 {
168 ib->len += attr_bin_write_attr(ab, attr);
169 }
170 }
171
172 static char *coord_to_str(struct coord *c);
173
174 void item_bin_remove_attr(struct item_bin *ib, void *ptr)
175 {
176 unsigned char *s = (unsigned char *) ib;
177 unsigned char *e = s + (ib->len + 1) * 4;
178 s += sizeof(struct item_bin) + ib->clen * 4;
179 while (s < e)
180 {
181 struct attr_bin *ab = (struct attr_bin *) s;
182 s += (ab->len + 1) * 4;
183 if ((void *) (ab + 1) == ptr)
184 {
185 ib->len -= ab->len + 1;
186 memmove(ab, s, e - s);
187 return;
188 }
189 }
190 }
191
192 void item_bin_add_attr_int(struct item_bin *ib, enum attr_type type, int val)
193 {
194 struct attr attr;
195 attr.type = type;
196 attr.u.num = val;
197 item_bin_add_attr(ib, &attr);
198 }
199
200 void *
201 item_bin_get_attr(struct item_bin *ib, enum attr_type type, void *last)
202 {
203 unsigned char *s = (unsigned char *) ib;
204 unsigned char *e = s + (ib->len + 1) * 4;
205 s += sizeof(struct item_bin) + ib->clen * 4;
206 while (s < e)
207 {
208 struct attr_bin *ab = (struct attr_bin *) s;
209 s += (ab->len + 1) * 4;
210 if (ab->type == type && (void *) (ab + 1) > last)
211 {
212 return (ab + 1);
213 }
214 }
215 return NULL;
216 }
217
218 struct attr_bin *
219 item_bin_get_attr_bin_last(struct item_bin *ib)
220 {
221 struct attr_bin *ab = NULL;
222 unsigned char *s = (unsigned char *) ib;
223 unsigned char *e = s + (ib->len + 1) * 4;
224 s += sizeof(struct item_bin) + ib->clen * 4;
225 while (s < e)
226 {
227 ab = (struct attr_bin *) s;
228 s += (ab->len + 1) * 4;
229 }
230 return ab;
231 }
232
233 void item_bin_add_attr_longlong(struct item_bin *ib, enum attr_type type, long long val)
234 {
235 struct attr attr;
236 attr.type = type;
237 attr.u.num64 = &val;
238 item_bin_add_attr(ib, &attr);
239 }
240
241 void item_bin_add_attr_string(struct item_bin *ib, enum attr_type type, char *str)
242 {
243 struct attr attr;
244 if (!str)
245 return;
246 attr.type = type;
247 attr.u.str = str;
248 item_bin_add_attr(ib, &attr);
249 }
250
251 void item_bin_add_attr_range(struct item_bin *ib, enum attr_type type, short min, short max)
252 {
253 struct attr attr;
254 attr.type = type;
255 attr.u.range.min = min;
256 attr.u.range.max = max;
257 item_bin_add_attr(ib, &attr);
258 }
259
260 void item_bin_write_xml(struct item_bin *ib, char *filename)
261 {
262 FILE *out = tempfile("", filename, 2);
263
264 struct coord *c;
265 struct attr_bin *a;
266 struct attr attr;
267 int *attr_start;
268 int *attr_end;
269 int i;
270 char *str;
271
272 c = (struct coord *) (ib + 1);
273
274 // LOTS of output ---------
275 if (ib->type < type_line)
276 {
277 //dump_coord(c, out);
278 // fprintf(out, " ");
279 }
280 // LOTS of output ---------
281
282
283 attr_start = (int *) (ib + 1) + ib->clen;
284 attr_end = (int *) ib + ib->len + 1;
285
286
287 // fprintf(out, "type=%s", item_to_name(ib->type));
288 // char *item_type = item_to_name(ib->type);
289
290 fprintf(out, "<way visible=\"true\" version=\"1\"");
291 // fprintf(out, "boundary=administrative,admin_level=2");
292
293 // "w boundary=administrative,admin_level=2 border_country\n"
294 // "w boundary=territorial,admin_level=2 border_country\n"
295 // "w boundary=maritime,admin_level=2 border_country\n"
296 // "w administrative=boundary,admin_level=2 border_country\n"
297 // "w boundary=administrative,maritime=yes,admin_level=2 border_country\n"
298 // "w boundary=administrative,maritime=yes,admin_level=4 border_country\n"
299 // "w boundary=administrative,border_type=state,admin_level=4 border_country\n" };
300
301
302 while (attr_start < attr_end)
303 {
304 a = (struct attr_bin *) (attr_start);
305 attr_start += a->len + 1;
306 attr.type = a->type;
307 attr_data_set(&attr, (a + 1));
308 str = attr_to_text(&attr, NULL, 1);
309
310 if (!strcmp("osm_wayid", attr_to_name(a->type)))
311 {
312 fprintf(out, " id=\"%s\"", str);
313 }
314 else
315 {
316 fprintf(out, " %s=\"%s\"", attr_to_name(a->type), str);
317 }
318 g_free(str);
319 }
320 // fprintf(out, " debug=\"length=%d\"", ib->len);
321 fprintf(out, ">\n");
322
323 // LOTS of output -----------
324 if (ib->type >= type_line)
325 {
326 // long x_;
327 long y_;
328 for (i = 0; i < ib->clen / 2; i++)
329 {
330 // x_ = (c + i)->x;
331 y_ = (c + i)->y;
332 fprintf(out, "<nd ref=\"%lu\"/>\n", y_);
333 }
334 }
335 // LOTS of output -----------
336
337 fprintf(out, "<tag k=\"admin_level\" v=\"2\"/>\n");
338 fprintf(out, "<tag k=\"boundary\" v=\"administrative\"/>\n");
339 fprintf(out, "</way>\n");
340
341 //if (debug_itembin(ib))
342 //{
343 // fprintf(stderr,"\n== item_bin_dump == END ==\n");
344 //}
345
346 fclose(out);
347 }
348
349 void item_bin_write(struct item_bin *ib, FILE *out)
350 {
351 if (debug_itembin(ib))
352 {
353 fprintf(stderr, "== item_bin_write == FILE: %p ==\n", out);
354 dump_itembin(ib);
355 fprintf(stderr, "== item_bin_write == END ==\n");
356 }
357
358 // long long t=(ib->len+1)*4;
359 // fprintf(stderr,"item_bin_write:fwrite "LONGLONG_FMT"\n", t);
360 fwrite(ib, (ib->len + 1) * 4, 1, out);
361 }
362
363 struct item_bin *
364 item_bin_dup(struct item_bin *ib)
365 {
366 int len = (ib->len + 1) * 4;
367 struct item_bin *ret = g_malloc(len);
368 memcpy(ret, ib, len);
369
370 return ret;
371 }
372
373 void item_bin_write_range(struct item_bin *ib, FILE *out, int min, int max)
374 {
375 struct range r;
376
377 r.min = min;
378 r.max = max;
379 fwrite(&r, sizeof(r), 1, out);
380 item_bin_write(ib, out);
381 }
382
383 void item_bin_write_clipped(struct item_bin *ib, struct tile_parameter *param, struct item_bin_sink *out)
384 {
385 struct tile_data tile_data;
386 int i;
387 bbox((struct coord *) (ib + 1), ib->clen / 2, &tile_data.item_bbox);
388 tile_data.buffer[0] = '\0';
389 tile_data.tile_depth = tile(&tile_data.item_bbox, NULL, tile_data.buffer, param->max, param->overlap, &tile_data.tile_bbox);
390 if (tile_data.tile_depth == param->max || tile_data.tile_depth >= param->min)
391 {
392 item_bin_write_to_sink(ib, out, &tile_data);
393 return;
394 }
395 for (i = 0; i < 4; i++)
396 {
397 struct rect clip_rect;
398 tile_data.buffer[tile_data.tile_depth] = 'a' + i;
399 tile_data.buffer[tile_data.tile_depth + 1] = '\0';
400 tile_bbox(tile_data.buffer, &clip_rect, param->overlap);
401 if (ib->type < type_area)
402 clip_line(ib, &clip_rect, param, out);
403 else
404 clip_polygon(ib, &clip_rect, param, out);
405 }
406 }
407
408 static char *
409 coord_to_str(struct coord *c)
410 {
411 int x = c->x;
412 int y = c->y;
413 char *sx = "";
414 char *sy = "";
415
416 if (x < 0)
417 {
418 sx = "-";
419 x = -x;
420 }
421
422 if (y < 0)
423 {
424 sy = "-";
425 y = -y;
426 }
427
428 return g_strdup_printf("%s0x%x %s0x%x", sx, x, sy, y);
429 }
430
431 static void dump_coord(struct coord *c, FILE *out)
432 {
433 char *str = coord_to_str(c);
434 fprintf(out, "%s", str);
435 g_free(str);
436 }
437
438 void item_bin_dump(struct item_bin *ib, FILE *out)
439 {
440 struct coord *c;
441 struct attr_bin *a;
442 struct attr attr;
443 int *attr_start;
444 int *attr_end;
445 int i;
446 char *str;
447
448 //if (debug_itembin(ib))
449 //{
450 // fprintf(stderr,"\n== item_bin_dump == START ==\n");
451 //}
452
453 c = (struct coord *) (ib + 1);
454
455 // LOTS of output ---------
456 if (ib->type < type_line)
457 {
458 dump_coord(c, out);
459 fprintf(out, " ");
460 }
461 // LOTS of output ---------
462
463
464 attr_start = (int *) (ib + 1) + ib->clen;
465 attr_end = (int *) ib + ib->len + 1;
466 fprintf(out, "type=%s", item_to_name(ib->type));
467 while (attr_start < attr_end)
468 {
469 a = (struct attr_bin *) (attr_start);
470 attr_start += a->len + 1;
471 attr.type = a->type;
472 attr_data_set(&attr, (a + 1));
473 str = attr_to_text(&attr, NULL, 1);
474 fprintf(out, " %s=\"%s\"", attr_to_name(a->type), str);
475 g_free(str);
476 }
477 fprintf(out, " debug=\"length=%d\"", ib->len);
478 fprintf(out, "\n");
479
480 // LOTS of output -----------
481 if (ib->type >= type_line)
482 {
483 for (i = 0; i < ib->clen / 2; i++)
484 {
485 dump_coord(c + i, out);
486 fprintf(out, "\n");
487 }
488 }
489 // LOTS of output -----------
490
491 //if (debug_itembin(ib))
492 //{
493 // fprintf(stderr,"\n== item_bin_dump == END ==\n");
494 //}
495 }
496
497 void dump_itembin(struct item_bin *ib)
498 {
499 // item_bin_dump(ib, stdout);
500 item_bin_dump(ib, stderr);
501 }
502
503 struct population_table
504 {
505 enum item_type type;
506 int population;
507 };
508
509 static struct population_table town_population[] =
510 {
511 { type_town_label_0e0, 0 },
512 { type_town_label_1e0, 1 },
513 { type_town_label_2e0, 2 },
514 { type_town_label_5e0, 5 },
515 { type_town_label_1e1, 10 },
516 { type_town_label_2e1, 20 },
517 { type_town_label_5e1, 50 },
518 { type_town_label_1e2, 100 },
519 { type_town_label_2e2, 200 },
520 { type_town_label_5e2, 500 },
521 { type_town_label_1e3, 1000 },
522 { type_town_label_2e3, 2000 },
523 { type_town_label_5e3, 5000 },
524 { type_town_label_1e4, 10000 },
525 { type_town_label_2e4, 20000 },
526 { type_town_label_5e4, 50000 },
527 { type_town_label_1e5, 100000 },
528 { type_town_label_2e5, 200000 },
529 { type_town_label_5e5, 500000 },
530 { type_town_label_1e6, 1000000 },
531 { type_town_label_2e6, 2000000 },
532 { type_town_label_5e6, 5000000 },
533 { type_town_label_1e7, 10000000 }, };
534
535 static struct population_table district_population[] =
536 {
537 { type_district_label_0e0, 0 },
538 { type_district_label_1e0, 1 },
539 { type_district_label_2e0, 2 },
540 { type_district_label_5e0, 5 },
541 { type_district_label_1e1, 10 },
542 { type_district_label_2e1, 20 },
543 { type_district_label_5e1, 50 },
544 { type_district_label_1e2, 100 },
545 { type_district_label_2e2, 200 },
546 { type_district_label_5e2, 500 },
547 { type_district_label_1e3, 1000 },
548 { type_district_label_2e3, 2000 },
549 { type_district_label_5e3, 5000 },
550 { type_district_label_1e4, 10000 },
551 { type_district_label_2e4, 20000 },
552 { type_district_label_5e4, 50000 },
553 { type_district_label_1e5, 100000 },
554 { type_district_label_2e5, 200000 },
555 { type_district_label_5e5, 500000 },
556 { type_district_label_1e6, 1000000 },
557 { type_district_label_2e6, 2000000 },
558 { type_district_label_5e6, 5000000 },
559 { type_district_label_1e7, 10000000 }, };
560
561 void item_bin_set_type_by_population(struct item_bin *ib, int population)
562 {
563 struct population_table *table;
564 int i, count;
565
566 if (population < 0)
567 population = 0;
568 if (item_is_district(*ib))
569 {
570 table = district_population;
571 count = sizeof(district_population) / sizeof(district_population[0]);
572 }
573 else
574 {
575 table = town_population;
576 count = sizeof(town_population) / sizeof(town_population[0]);
577 }
578 for (i = 0; i < count; i++)
579 {
580 if (population < table[i].population)
581 break;
582 }
583 item_bin_set_type(ib, table[i - 1].type);
584 }
585
586 void item_bin_town_write_match(struct item_bin *ib, enum attr_type type, enum attr_type match, FILE *out)
587 {
588 char *word_orig = item_bin_get_attr(ib, type, NULL);
589 int i;
590 // ?? int len=ib->len;
591
592 if (!word_orig)
593 {
594 // fprintf(stderr,"**** NULL value ****\n");
595 return;
596 }
597
598 // fprintf(stderr,"###################################\n");
599 // fprintf(stderr,"###################################\n");
600 // fprintf(stderr,"name=%s\n",word_orig);
601
602 // xx ++ item_bin_add_attr_string(ib, match, str);
603
604 //for (i = 1 ; i < 2 ; i++)
605 //{
606 i = 1;
607 char *str = linguistics_expand_special(word_orig, i);
608 if (str)
609 {
610 char *str2;
611 str2 = linguistics_casefold(str);
612 if (str2)
613 {
614 // ?? ib->len=len-(len-strlen(str2));
615 //fprintf(stderr,"i=%d match1=%s\n",i,str);
616 //fprintf(stderr,"i=%d match2=%s\n",i,str2);
617 item_bin_add_attr_string(ib, match, str2);
618 g_free(str2);
619 }
620 g_free(str);
621 }
622 //}
623
624 item_bin_write(ib, out);
625
626 //if (word_orig!=NULL)
627 //{
628 // g_free(word_orig);
629 //}
630 }
631
632 void item_bin_write_match(struct item_bin *ib, enum attr_type type, enum attr_type match, FILE *out)
633 {
634 char *word = item_bin_get_attr(ib, type, NULL);
635 int i;
636 //int words=0;
637 int len = ib->len;
638 //int first=1;
639 if (!word)
640 {
641 return;
642 }
643
644 if (debug_itembin(ib))
645 {
646 fprintf(stderr, "###################################\n");
647 fprintf(stderr, "###################################\n");
648 fprintf(stderr, "name=%s\n", word);
649 }
650
651 word = linguistics_next_word(word);
652
653 while (word)
654 {
655 if (debug_itembin(ib))
656 {
657 fprintf(stderr, "word=%s\n", word);
658 }
659 for (i = 0; i < 3; i++)
660 {
661 char *str = linguistics_expand_special(word, i);
662 if (str)
663 {
664 ib->len = len;
665 if (debug_itembin(ib))
666 {
667 fprintf(stderr, "i=%d match=%s\n", i, str);
668 }
669 item_bin_add_attr_string(ib, match, str);
670 item_bin_write(ib, out);
671 g_free(str);
672 }
673 }
674 word = linguistics_next_word(NULL);
675 }
676
677 if (word != NULL)
678 {
679 g_free(word);
680 }
681 }
682
683 static int item_bin_sort_compare(const void *p1, const void *p2)
684 {
685 struct item_bin *ib1 = *((struct item_bin **) p1), *ib2 = *((struct item_bin **) p2);
686 struct attr_bin *attr1, *attr2;
687 char *s1, *s2;
688 int ret;
689
690 #if 0
691 dbg_assert(ib1->clen==2);
692 dbg_assert(ib2->clen==2);
693 attr1=(struct attr_bin *)((int *)(ib1+1)+ib1->clen);
694 attr2=(struct attr_bin *)((int *)(ib2+1)+ib1->clen);
695 #else
696 attr1 = item_bin_get_attr_bin_last(ib1);
697 attr2 = item_bin_get_attr_bin_last(ib2);
698 #endif
699 #if 0
700 dbg_assert(attr1->type == attr_town_name || attr1->type == attr_town_name_match);
701 dbg_assert(attr2->type == attr_town_name || attr2->type == attr_town_name_match);
702 #endif
703 s1 = (char *) (attr1 + 1);
704 s2 = (char *) (attr2 + 1);
705 if (attr1->type == attr_house_number && attr2->type == attr_house_number)
706 {
707 ret = atoi(s1) - atoi(s2);
708 if (ret)
709 {
710 return ret;
711 }
712 }
713 ret = strcmp(s1, s2);
714 if (!ret)
715 {
716 int match1 = 0, match2 = 0;
717 match1 = (attr1->type == attr_town_name_match || attr1->type == attr_district_name_match);
718 match2 = (attr2->type == attr_town_name_match || attr2->type == attr_district_name_match);
719 ret = match1 - match2;
720 }
721
722 #if 0
723 fprintf(stderr,"sort_countries_compare p1=%p p2=%p %s %s\n",p1,p2,s1,s2);
724 #endif
725
726 return ret;
727 }
728
729 int item_bin_sort_file(char *in_file, char *out_file, struct rect *r, int *size)
730 {
731 int j, k, count, rc = 0;
732 struct coord *c;
733 struct item_bin *ib;
734 FILE *f;
735 unsigned char *p, **idx, *buffer;
736 if (file_get_contents(in_file, &buffer, size))
737 {
738 ib = (struct item_bin *) buffer;
739 p = buffer;
740 count = 0;
741 while (p < buffer + *size)
742 {
743 count++;
744 p += (*((int *) p) + 1) * 4;
745 }
746 idx = malloc(count * sizeof(void *));
747 dbg_assert(idx != NULL);
748 p = buffer;
749 for (j = 0; j < count; j++)
750 {
751 idx[j] = p;
752 p += (*((int *) p) + 1) * 4;
753 }
754 qsort(idx, count, sizeof(void *), item_bin_sort_compare);
755 f = fopen(out_file, "wb");
756 for (j = 0; j < count; j++)
757 {
758 ib = (struct item_bin *) (idx[j]);
759 c = (struct coord *) (ib + 1);
760 fwrite(ib, (ib->len + 1) * 4, 1, f);
761 if (r)
762 {
763 for (k = 0; k < ib->clen / 2; k++)
764 {
765 if (rc)
766 bbox_extend(&c[k], r);
767 else
768 {
769 r->l = c[k];
770 r->h = c[k];
771 }
772 rc++;
773 }
774 }
775 }
776 fclose(f);
777 return 1;
778 }
779 return 0;
780 }
781

   
Visit the ZANavi Wiki