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

Contents of /navit/navit/maptool/misc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Mon Feb 4 17:41:59 2013 UTC (7 years, 7 months ago) by zoff99
File MIME type: text/plain
File size: 11708 byte(s)
new map version, lots of fixes and experimental new features
1 zoff99 8 /**
2 zoff99 31 * 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 zoff99 8 * Navit, a modular navigation system.
22     * Copyright (C) 2005-2008 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 <stdlib.h>
43     #include <glib.h>
44     #include <assert.h>
45     #include <string.h>
46     #include <signal.h>
47     #include <stdio.h>
48     #include <math.h>
49     #include <getopt.h>
50     #include <unistd.h>
51     #include <fcntl.h>
52     #include <sys/stat.h>
53     #include <zlib.h>
54     #include "file.h"
55     #include "item.h"
56     #include "map.h"
57     #include "zipfile.h"
58     #include "main.h"
59     #include "config.h"
60     #include "linguistics.h"
61     #include "plugin.h"
62     #include "maptool.h"
63    
64 zoff99 31 struct rect world_bbox =
65     {
66     { -20000000, -20000000 },
67     { 20000000, 20000000 }, };
68 zoff99 8
69 zoff99 31 void bbox_extend(struct coord *c, struct rect *r)
70 zoff99 8 {
71     if (c->x < r->l.x)
72 zoff99 31 r->l.x = c->x;
73 zoff99 8 if (c->y < r->l.y)
74 zoff99 31 r->l.y = c->y;
75 zoff99 8 if (c->x > r->h.x)
76 zoff99 31 r->h.x = c->x;
77 zoff99 8 if (c->y > r->h.y)
78 zoff99 31 r->h.y = c->y;
79 zoff99 8 }
80    
81 zoff99 31 void bbox(struct coord *c, int count, struct rect *r)
82 zoff99 8 {
83 zoff99 31 if (!count)
84 zoff99 8 return;
85 zoff99 31 r->l = *c;
86     r->h = *c;
87     while (--count)
88     {
89 zoff99 8 c++;
90     bbox_extend(c, r);
91     }
92     }
93    
94 zoff99 31 int contains_bbox(int xl, int yl, int xh, int yh, struct rect *r)
95 zoff99 8 {
96 zoff99 31 if (r->h.x < xl || r->h.x > xh)
97     {
98 zoff99 8 return 0;
99     }
100 zoff99 31 if (r->l.x > xh || r->l.x < xl)
101     {
102 zoff99 8 return 0;
103     }
104 zoff99 31 if (r->h.y < yl || r->h.y > yh)
105     {
106 zoff99 8 return 0;
107     }
108 zoff99 31 if (r->l.y > yh || r->l.y < yl)
109     {
110 zoff99 8 return 0;
111     }
112     return 1;
113     }
114    
115 zoff99 31 int bbox_contains_coord(struct rect *r, struct coord *c)
116 zoff99 8 {
117 zoff99 31
118     //fprintf(stderr,"bbox_contains_coord: rhx=%d rhy=%d rlx=%d rly=%d, cx=%d cy=%d\n", r->h.x, r->h.y, r->l.x, r->l.y,c->x, c->y);
119    
120 zoff99 8 if (r->h.x < c->x)
121     return 0;
122     if (r->l.x > c->x)
123     return 0;
124     if (r->h.y < c->y)
125     return 0;
126     if (r->l.y > c->y)
127     return 0;
128     return 1;
129     }
130    
131 zoff99 31 int bbox_contains_bbox(struct rect *out, struct rect *in)
132 zoff99 8 {
133     if (out->h.x < in->h.x)
134     return 0;
135     if (out->l.x > in->l.x)
136     return 0;
137     if (out->h.y < in->h.y)
138     return 0;
139     if (out->l.y > in->l.y)
140     return 0;
141     return 1;
142     }
143    
144 zoff99 31 long long bbox_area(struct rect const *r)
145 zoff99 8 {
146 zoff99 31 return ((long long) r->h.x - r->l.x) * (r->h.y - r->l.y);
147 zoff99 8 }
148    
149 zoff99 31 void phase1_map(GList *maps, FILE *out_ways, FILE *out_nodes)
150 zoff99 8 {
151     struct map_rect *mr;
152     struct item *item;
153 zoff99 31 int count, max = 16384;
154 zoff99 8 struct coord ca[max];
155     struct attr attr;
156     struct item_bin *item_bin;
157    
158 zoff99 31 while (maps)
159     {
160     mr = map_rect_new(maps->data, NULL);
161     while ((item = map_rect_get_item(mr)))
162     {
163     count = item_coord_get(item, ca, item->type < type_line ? 1 : max);
164     item_bin = init_item(item->type, 0);
165 zoff99 8 item_bin_add_coord(item_bin, ca, count);
166 zoff99 31 while (item_attr_get(item, attr_any, &attr))
167     {
168     if (attr.type >= attr_type_string_begin && attr.type <= attr_type_string_end)
169     {
170     attr.u.str = map_convert_string(maps->data, attr.u.str);
171     if (attr.u.str)
172     {
173 zoff99 8 item_bin_add_attr(item_bin, &attr);
174     map_convert_free(attr.u.str);
175     }
176 zoff99 31 }
177     else
178 zoff99 8 item_bin_add_attr(item_bin, &attr);
179     }
180 zoff99 31 if (item->type >= type_line)
181 zoff99 8 item_bin_write(item_bin, out_ways);
182     else
183     item_bin_write(item_bin, out_nodes);
184     }
185     map_rect_destroy(mr);
186 zoff99 31 maps = g_list_next(maps);
187 zoff99 8 }
188     }
189    
190 zoff99 31 static void phase34_process_file(struct tile_info *info, FILE *in, FILE *reference)
191 zoff99 8 {
192     struct item_bin *ib;
193     int max;
194    
195 zoff99 31 while ((ib = read_item(in, 0)))
196     {
197 zoff99 8 if (ib->type < 0x80000000)
198 zoff99 31 {
199 zoff99 8 processed_nodes++;
200 zoff99 31 }
201 zoff99 8 else
202 zoff99 31 {
203 zoff99 8 processed_ways++;
204     }
205 zoff99 31
206     if (border_only_map == 1)
207     {
208     // fprintf(stderr,"max=1\n");
209     // max=1; --> shows all borders, all the time. but is too slow!
210     max = 4;
211     }
212     else
213     {
214     max = 14;
215     switch (ib->type)
216     {
217     case type_town_label_1e7:
218     case type_town_label_5e6:
219     case type_town_label_2e6:
220     case type_town_label_1e6:
221     case type_town_label_5e5:
222     case type_district_label_1e7:
223     case type_district_label_5e6:
224     case type_district_label_2e6:
225     case type_district_label_1e6:
226     case type_district_label_5e5:
227     max = 6;
228     break;
229     case type_town_label_2e5:
230     case type_town_label_1e5:
231     case type_district_label_2e5:
232     case type_district_label_1e5:
233     case type_street_n_lanes:
234     case type_highway_city:
235     case type_highway_land:
236     case type_ramp:
237     max = 8;
238     break;
239     case type_town_label_5e4:
240     case type_town_label_2e4:
241     case type_town_label_1e4:
242     case type_district_label_5e4:
243     case type_district_label_2e4:
244     case type_district_label_1e4:
245     max = 9;
246     break;
247     case type_street_4_land:
248     case type_street_4_city:
249     max = 10;
250     break;
251     case type_town_label_5e3:
252     case type_town_label_2e3:
253     case type_town_label_1e3:
254     case type_district_label_5e3:
255     case type_district_label_2e3:
256     case type_district_label_1e3:
257     case type_street_3_city:
258     case type_street_3_land:
259     max = 12;
260     break;
261     default:
262     break;
263     }
264     }
265    
266     // dont write "street unknown" items to binfile, if option "to ignore unknown types" is set
267     if ((ib->type == type_street_unkn) && (ignore_unkown == 1))
268     {
269     }
270     else
271     {
272     tile_write_item_minmax(info, ib, reference, 0, max);
273     }
274 zoff99 8 }
275     }
276    
277 zoff99 31 static void phase34_process_file_range(struct tile_info *info, FILE *in, FILE *reference)
278 zoff99 8 {
279     struct item_bin *ib;
280 zoff99 31 int min, max;
281 zoff99 8
282 zoff99 31 while ((ib = read_item_range(in, &min, &max, 0)))
283     {
284 zoff99 8 if (ib->type < 0x80000000)
285     processed_nodes++;
286     else
287     processed_ways++;
288 zoff99 31
289     if ((ib->type == type_street_unkn) && (ignore_unkown == 1))
290     {
291     }
292     else
293     {
294     tile_write_item_minmax(info, ib, reference, min, max);
295     }
296 zoff99 8 }
297     }
298    
299 zoff99 31 static int phase34(struct tile_info *info, struct zip_info *zip_info, FILE **in, FILE **reference, int in_count, int with_range)
300 zoff99 8 {
301     int i;
302    
303 zoff99 31 processed_nodes = processed_nodes_out = processed_ways = processed_relations = processed_tiles = 0;
304    
305     bytes_read = 0;
306     //sig_alrm(0);
307    
308     if (!info->write)
309     {
310     tile_hash = g_hash_table_new(g_str_hash, g_str_equal);
311     }
312    
313     for (i = 0; i < in_count; i++)
314     {
315     if (in[i])
316     {
317 zoff99 8 if (with_range)
318 zoff99 31 {
319     phase34_process_file_range(info, in[i], reference ? reference[i] : NULL);
320     }
321 zoff99 8 else
322 zoff99 31 {
323     phase34_process_file(info, in[i], reference ? reference[i] : NULL);
324     }
325 zoff99 8 }
326     }
327 zoff99 31
328     if (!info->write)
329     {
330 zoff99 8 merge_tiles(info);
331 zoff99 31 }
332    
333     //sig_alrm(0);
334     //sig_alrm_end();
335    
336 zoff99 8 write_tilesdir(info, zip_info, info->tilesdir_out);
337    
338     return 0;
339    
340     }
341    
342 zoff99 31 void dump(FILE *in)
343 zoff99 8 {
344     struct item_bin *ib;
345 zoff99 31 while ((ib = read_item(in, 0)))
346     {
347 zoff99 8 dump_itembin(ib);
348     }
349     }
350    
351 zoff99 31 int phase4(FILE **in, int in_count, int with_range, char *suffix, FILE *tilesdir_out, struct zip_info *zip_info)
352 zoff99 8 {
353     struct tile_info info;
354 zoff99 31 info.write = 0;
355     info.maxlen = 0;
356     info.suffix = suffix;
357     info.tiles_list = NULL;
358     info.tilesdir_out = tilesdir_out;
359 zoff99 8 return phase34(&info, zip_info, in, NULL, in_count, with_range);
360     }
361    
362 zoff99 31 static int process_slice(FILE **in, FILE **reference, int in_count, int with_range, long long size, char *suffix, struct zip_info *zip_info)
363 zoff99 8 {
364     struct tile_head *th;
365 zoff99 31 char *slice_data, *zip_data;
366     int zipfiles = 0;
367 zoff99 8 struct tile_info info;
368     int i;
369    
370 zoff99 31 slice_data = malloc(size);
371 zoff99 8 assert(slice_data != NULL);
372 zoff99 31 zip_data = slice_data;
373     th = tile_head_root;
374     while (th)
375     {
376     if (th->process)
377     {
378     th->zip_data = zip_data;
379     zip_data += th->total_size;
380 zoff99 8 }
381 zoff99 31 th = th->next;
382 zoff99 8 }
383 zoff99 31 for (i = 0; i < in_count; i++)
384     {
385 zoff99 8 if (in[i])
386     fseek(in[i], 0, SEEK_SET);
387 zoff99 31 if (reference && reference[i])
388     {
389 zoff99 8 fseek(reference[i], 0, SEEK_SET);
390     }
391     }
392 zoff99 31 info.write = 1;
393     info.maxlen = zip_get_maxnamelen(zip_info);
394     info.suffix = suffix;
395     info.tiles_list = NULL;
396     info.tilesdir_out = NULL;
397 zoff99 8 phase34(&info, zip_info, in, reference, in_count, with_range);
398    
399 zoff99 31 th = tile_head_root;
400     while (th)
401     {
402     if (th->process)
403     {
404     if (th->name[0])
405     {
406     if (th->total_size != th->total_size_used)
407     {
408     fprintf(stderr, "Size error '%s': %d vs %d\n", th->name, th->total_size, th->total_size_used);
409 zoff99 8 exit(1);
410     }
411     write_zipmember(zip_info, th->name, zip_get_maxnamelen(zip_info), th->zip_data, th->total_size);
412     zipfiles++;
413 zoff99 31 }
414     else
415 zoff99 8 fwrite(th->zip_data, th->total_size, 1, zip_get_index(zip_info));
416     }
417 zoff99 31 th = th->next;
418 zoff99 8 }
419     free(slice_data);
420    
421     return zipfiles;
422     }
423    
424 zoff99 31 int phase5(FILE **in, FILE **references, int in_count, int with_range, char *suffix, struct zip_info *zip_info)
425 zoff99 8 {
426     long long size;
427     int slices;
428 zoff99 31 int zipnum, written_tiles;
429     struct tile_head *th, *th2;
430    
431     time_t start_tt, end_tt;
432     double diff_tt;
433     double diff2_tt;
434    
435 zoff99 8 create_tile_hash();
436    
437 zoff99 31 th = tile_head_root;
438     size = 0;
439     slices = 0;
440 zoff99 8 fprintf(stderr, "Maximum slice size "LONGLONG_FMT"\n", slice_size);
441 zoff99 31 while (th)
442     {
443     if (size + th->total_size > slice_size)
444     {
445 zoff99 8 fprintf(stderr,"Slice %d is of size "LONGLONG_FMT"\n", slices, size);
446 zoff99 31 size = 0;
447 zoff99 8 slices++;
448     }
449 zoff99 31 size += th->total_size;
450     th = th->next;
451 zoff99 8 }
452 zoff99 31
453 zoff99 8 if (size)
454 zoff99 31 {
455 zoff99 8 fprintf(stderr,"Slice %d is of size "LONGLONG_FMT"\n", slices, size);
456 zoff99 31 }
457    
458     int max_slices_ = slices;
459     th = tile_head_root;
460     size = 0;
461     slices = 0;
462    
463     while (th)
464     {
465     time(&start_tt);
466    
467     fprintf(stderr,"Slice #%d of %d\n", (slices + 1), (max_slices_ + 1));
468    
469     th2 = tile_head_root;
470     while (th2)
471     {
472     th2->process = 0;
473     th2 = th2->next;
474 zoff99 8 }
475 zoff99 31
476     size = 0;
477     while (th && size + th->total_size < slice_size)
478     {
479     size += th->total_size;
480     th->process = 1;
481     th = th->next;
482 zoff99 8 }
483 zoff99 31
484 zoff99 8 /* process_slice() modifies zip_info, but need to retain old info */
485 zoff99 31 zipnum = zip_get_zipnum(zip_info);
486     written_tiles = process_slice(in, references, in_count, with_range, size, suffix, zip_info);
487     zip_set_zipnum(zip_info, zipnum + written_tiles);
488    
489     time(&end_tt);
490     diff_tt = difftime(end_tt,start_tt);
491     char outstring[200];
492     convert_to_human_time(diff_tt, outstring);
493     fprintf(stderr, "-RUNTIME-LOOP-PHASE5: %s this loop run\n", outstring);
494     diff2_tt = diff2_tt + diff_tt;
495     if ((slices + 1) > 0)
496     {
497     double eta_time = (diff2_tt / (slices + 1)) * (max_slices_ + 1 - (slices + 1));
498     convert_to_human_time(eta_time, outstring);
499     fprintf(stderr, "-RUNTIME-LOOP-PHASE5: %s left\n", outstring);
500     }
501    
502 zoff99 8 slices++;
503     }
504 zoff99 31
505 zoff99 8 return 0;
506     }
507    
508 zoff99 31 void process_binfile(FILE *in, FILE *out)
509 zoff99 8 {
510     struct item_bin *ib;
511 zoff99 31 while ((ib = read_item(in, 0)))
512     {
513     fwrite(ib, (ib->len + 1) * 4, 1, out);
514 zoff99 8 }
515     }
516    
517 zoff99 31 void add_aux_tiles(char *name, struct zip_info *info)
518 zoff99 8 {
519     char buffer[4096];
520     char *s;
521     FILE *in;
522     FILE *tmp;
523 zoff99 31 in = fopen(name, "rb");
524 zoff99 8 if (!in)
525     return;
526 zoff99 31 while (fscanf(in, "%s", buffer) == 1)
527     {
528     s = strchr(buffer, '/');
529 zoff99 8 if (s)
530     s++;
531     else
532 zoff99 31 s = buffer;
533     tmp = fopen(buffer, "rb");
534     if (tmp)
535     {
536 zoff99 8 fseek(tmp, 0, SEEK_END);
537     add_aux_tile(info, s, buffer, ftell(tmp));
538     fclose(tmp);
539     }
540     }
541     fclose(in);
542     }

   
Visit the ZANavi Wiki