/[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 - (show annotations) (download)
Mon Feb 4 17:41:59 2013 UTC (7 years, 6 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 /**
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-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 struct rect world_bbox =
65 {
66 { -20000000, -20000000 },
67 { 20000000, 20000000 }, };
68
69 void bbox_extend(struct coord *c, struct rect *r)
70 {
71 if (c->x < r->l.x)
72 r->l.x = c->x;
73 if (c->y < r->l.y)
74 r->l.y = c->y;
75 if (c->x > r->h.x)
76 r->h.x = c->x;
77 if (c->y > r->h.y)
78 r->h.y = c->y;
79 }
80
81 void bbox(struct coord *c, int count, struct rect *r)
82 {
83 if (!count)
84 return;
85 r->l = *c;
86 r->h = *c;
87 while (--count)
88 {
89 c++;
90 bbox_extend(c, r);
91 }
92 }
93
94 int contains_bbox(int xl, int yl, int xh, int yh, struct rect *r)
95 {
96 if (r->h.x < xl || r->h.x > xh)
97 {
98 return 0;
99 }
100 if (r->l.x > xh || r->l.x < xl)
101 {
102 return 0;
103 }
104 if (r->h.y < yl || r->h.y > yh)
105 {
106 return 0;
107 }
108 if (r->l.y > yh || r->l.y < yl)
109 {
110 return 0;
111 }
112 return 1;
113 }
114
115 int bbox_contains_coord(struct rect *r, struct coord *c)
116 {
117
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 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 int bbox_contains_bbox(struct rect *out, struct rect *in)
132 {
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 long long bbox_area(struct rect const *r)
145 {
146 return ((long long) r->h.x - r->l.x) * (r->h.y - r->l.y);
147 }
148
149 void phase1_map(GList *maps, FILE *out_ways, FILE *out_nodes)
150 {
151 struct map_rect *mr;
152 struct item *item;
153 int count, max = 16384;
154 struct coord ca[max];
155 struct attr attr;
156 struct item_bin *item_bin;
157
158 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 item_bin_add_coord(item_bin, ca, count);
166 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 item_bin_add_attr(item_bin, &attr);
174 map_convert_free(attr.u.str);
175 }
176 }
177 else
178 item_bin_add_attr(item_bin, &attr);
179 }
180 if (item->type >= type_line)
181 item_bin_write(item_bin, out_ways);
182 else
183 item_bin_write(item_bin, out_nodes);
184 }
185 map_rect_destroy(mr);
186 maps = g_list_next(maps);
187 }
188 }
189
190 static void phase34_process_file(struct tile_info *info, FILE *in, FILE *reference)
191 {
192 struct item_bin *ib;
193 int max;
194
195 while ((ib = read_item(in, 0)))
196 {
197 if (ib->type < 0x80000000)
198 {
199 processed_nodes++;
200 }
201 else
202 {
203 processed_ways++;
204 }
205
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 }
275 }
276
277 static void phase34_process_file_range(struct tile_info *info, FILE *in, FILE *reference)
278 {
279 struct item_bin *ib;
280 int min, max;
281
282 while ((ib = read_item_range(in, &min, &max, 0)))
283 {
284 if (ib->type < 0x80000000)
285 processed_nodes++;
286 else
287 processed_ways++;
288
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 }
297 }
298
299 static int phase34(struct tile_info *info, struct zip_info *zip_info, FILE **in, FILE **reference, int in_count, int with_range)
300 {
301 int i;
302
303 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 if (with_range)
318 {
319 phase34_process_file_range(info, in[i], reference ? reference[i] : NULL);
320 }
321 else
322 {
323 phase34_process_file(info, in[i], reference ? reference[i] : NULL);
324 }
325 }
326 }
327
328 if (!info->write)
329 {
330 merge_tiles(info);
331 }
332
333 //sig_alrm(0);
334 //sig_alrm_end();
335
336 write_tilesdir(info, zip_info, info->tilesdir_out);
337
338 return 0;
339
340 }
341
342 void dump(FILE *in)
343 {
344 struct item_bin *ib;
345 while ((ib = read_item(in, 0)))
346 {
347 dump_itembin(ib);
348 }
349 }
350
351 int phase4(FILE **in, int in_count, int with_range, char *suffix, FILE *tilesdir_out, struct zip_info *zip_info)
352 {
353 struct tile_info info;
354 info.write = 0;
355 info.maxlen = 0;
356 info.suffix = suffix;
357 info.tiles_list = NULL;
358 info.tilesdir_out = tilesdir_out;
359 return phase34(&info, zip_info, in, NULL, in_count, with_range);
360 }
361
362 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 {
364 struct tile_head *th;
365 char *slice_data, *zip_data;
366 int zipfiles = 0;
367 struct tile_info info;
368 int i;
369
370 slice_data = malloc(size);
371 assert(slice_data != NULL);
372 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 }
381 th = th->next;
382 }
383 for (i = 0; i < in_count; i++)
384 {
385 if (in[i])
386 fseek(in[i], 0, SEEK_SET);
387 if (reference && reference[i])
388 {
389 fseek(reference[i], 0, SEEK_SET);
390 }
391 }
392 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 phase34(&info, zip_info, in, reference, in_count, with_range);
398
399 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 exit(1);
410 }
411 write_zipmember(zip_info, th->name, zip_get_maxnamelen(zip_info), th->zip_data, th->total_size);
412 zipfiles++;
413 }
414 else
415 fwrite(th->zip_data, th->total_size, 1, zip_get_index(zip_info));
416 }
417 th = th->next;
418 }
419 free(slice_data);
420
421 return zipfiles;
422 }
423
424 int phase5(FILE **in, FILE **references, int in_count, int with_range, char *suffix, struct zip_info *zip_info)
425 {
426 long long size;
427 int slices;
428 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 create_tile_hash();
436
437 th = tile_head_root;
438 size = 0;
439 slices = 0;
440 fprintf(stderr, "Maximum slice size "LONGLONG_FMT"\n", slice_size);
441 while (th)
442 {
443 if (size + th->total_size > slice_size)
444 {
445 fprintf(stderr,"Slice %d is of size "LONGLONG_FMT"\n", slices, size);
446 size = 0;
447 slices++;
448 }
449 size += th->total_size;
450 th = th->next;
451 }
452
453 if (size)
454 {
455 fprintf(stderr,"Slice %d is of size "LONGLONG_FMT"\n", slices, size);
456 }
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 }
475
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 }
483
484 /* process_slice() modifies zip_info, but need to retain old info */
485 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 slices++;
503 }
504
505 return 0;
506 }
507
508 void process_binfile(FILE *in, FILE *out)
509 {
510 struct item_bin *ib;
511 while ((ib = read_item(in, 0)))
512 {
513 fwrite(ib, (ib->len + 1) * 4, 1, out);
514 }
515 }
516
517 void add_aux_tiles(char *name, struct zip_info *info)
518 {
519 char buffer[4096];
520 char *s;
521 FILE *in;
522 FILE *tmp;
523 in = fopen(name, "rb");
524 if (!in)
525 return;
526 while (fscanf(in, "%s", buffer) == 1)
527 {
528 s = strchr(buffer, '/');
529 if (s)
530 s++;
531 else
532 s = buffer;
533 tmp = fopen(buffer, "rb");
534 if (tmp)
535 {
536 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