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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

   
Visit the ZANavi Wiki