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

Contents of /navit/navit/maptool/misc.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: 9318 byte(s)
import
1 /**
2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2008 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
21 #define _FILE_OFFSET_BITS 64
22 #define _LARGEFILE_SOURCE
23 #define _LARGEFILE64_SOURCE
24 #include <stdlib.h>
25 #include <glib.h>
26 #include <assert.h>
27 #include <string.h>
28 #include <signal.h>
29 #include <stdio.h>
30 #include <math.h>
31 #include <getopt.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <sys/stat.h>
35 #include <zlib.h>
36 #include "file.h"
37 #include "item.h"
38 #include "map.h"
39 #include "zipfile.h"
40 #include "main.h"
41 #include "config.h"
42 #include "linguistics.h"
43 #include "plugin.h"
44 #include "maptool.h"
45
46 struct rect world_bbox = {
47 { -20000000, -20000000},
48 { 20000000, 20000000},
49 };
50
51 void
52 bbox_extend(struct coord *c, struct rect *r)
53 {
54 if (c->x < r->l.x)
55 r->l.x=c->x;
56 if (c->y < r->l.y)
57 r->l.y=c->y;
58 if (c->x > r->h.x)
59 r->h.x=c->x;
60 if (c->y > r->h.y)
61 r->h.y=c->y;
62 }
63
64 void
65 bbox(struct coord *c, int count, struct rect *r)
66 {
67 if (! count)
68 return;
69 r->l=*c;
70 r->h=*c;
71 while (--count) {
72 c++;
73 bbox_extend(c, r);
74 }
75 }
76
77 int
78 contains_bbox(int xl, int yl, int xh, int yh, struct rect *r)
79 {
80 if (r->h.x < xl || r->h.x > xh) {
81 return 0;
82 }
83 if (r->l.x > xh || r->l.x < xl) {
84 return 0;
85 }
86 if (r->h.y < yl || r->h.y > yh) {
87 return 0;
88 }
89 if (r->l.y > yh || r->l.y < yl) {
90 return 0;
91 }
92 return 1;
93 }
94
95 int
96 bbox_contains_coord(struct rect *r, struct coord *c)
97 {
98 if (r->h.x < c->x)
99 return 0;
100 if (r->l.x > c->x)
101 return 0;
102 if (r->h.y < c->y)
103 return 0;
104 if (r->l.y > c->y)
105 return 0;
106 return 1;
107 }
108
109 int
110 bbox_contains_bbox(struct rect *out, struct rect *in)
111 {
112 if (out->h.x < in->h.x)
113 return 0;
114 if (out->l.x > in->l.x)
115 return 0;
116 if (out->h.y < in->h.y)
117 return 0;
118 if (out->l.y > in->l.y)
119 return 0;
120 return 1;
121 }
122
123 long long
124 bbox_area(struct rect const *r)
125 {
126 return ((long long)r->h.x-r->l.x)*(r->h.y-r->l.y);
127 }
128
129 void
130 phase1_map(GList *maps, FILE *out_ways, FILE *out_nodes)
131 {
132 struct map_rect *mr;
133 struct item *item;
134 int count,max=16384;
135 struct coord ca[max];
136 struct attr attr;
137 struct item_bin *item_bin;
138
139 while (maps) {
140 mr=map_rect_new(maps->data, NULL);
141 while ((item = map_rect_get_item(mr))) {
142 count=item_coord_get(item, ca, item->type < type_line ? 1: max);
143 item_bin=init_item(item->type);
144 item_bin_add_coord(item_bin, ca, count);
145 while (item_attr_get(item, attr_any, &attr)) {
146 if (attr.type >= attr_type_string_begin && attr.type <= attr_type_string_end) {
147 attr.u.str=map_convert_string(maps->data, attr.u.str);
148 if (attr.u.str) {
149 item_bin_add_attr(item_bin, &attr);
150 map_convert_free(attr.u.str);
151 }
152 } else
153 item_bin_add_attr(item_bin, &attr);
154 }
155 if (item->type >= type_line)
156 item_bin_write(item_bin, out_ways);
157 else
158 item_bin_write(item_bin, out_nodes);
159 }
160 map_rect_destroy(mr);
161 maps=g_list_next(maps);
162 }
163 }
164
165 static void
166 phase34_process_file(struct tile_info *info, FILE *in, FILE *reference)
167 {
168 struct item_bin *ib;
169 int max;
170
171 while ((ib=read_item(in))) {
172 if (ib->type < 0x80000000)
173 processed_nodes++;
174 else
175 processed_ways++;
176 max=14;
177 switch (ib->type) {
178 case type_town_label_1e7:
179 case type_town_label_5e6:
180 case type_town_label_2e6:
181 case type_town_label_1e6:
182 case type_town_label_5e5:
183 case type_district_label_1e7:
184 case type_district_label_5e6:
185 case type_district_label_2e6:
186 case type_district_label_1e6:
187 case type_district_label_5e5:
188 max=6;
189 break;
190 case type_town_label_2e5:
191 case type_town_label_1e5:
192 case type_district_label_2e5:
193 case type_district_label_1e5:
194 case type_street_n_lanes:
195 case type_highway_city:
196 case type_highway_land:
197 case type_ramp:
198 max=8;
199 break;
200 case type_town_label_5e4:
201 case type_town_label_2e4:
202 case type_town_label_1e4:
203 case type_district_label_5e4:
204 case type_district_label_2e4:
205 case type_district_label_1e4:
206 max=9;
207 break;
208 case type_town_label_5e3:
209 case type_town_label_2e3:
210 case type_town_label_1e3:
211 case type_district_label_5e3:
212 case type_district_label_2e3:
213 case type_district_label_1e3:
214 case type_street_3_city:
215 case type_street_4_city:
216 case type_street_3_land:
217 case type_street_4_land:
218 max=12;
219 break;
220 default:
221 break;
222 }
223 tile_write_item_minmax(info, ib, reference, 0, max);
224 }
225 }
226
227 static void
228 phase34_process_file_range(struct tile_info *info, FILE *in, FILE *reference)
229 {
230 struct item_bin *ib;
231 int min,max;
232
233 while ((ib=read_item_range(in, &min, &max))) {
234 if (ib->type < 0x80000000)
235 processed_nodes++;
236 else
237 processed_ways++;
238 tile_write_item_minmax(info, ib, reference, min, max);
239 }
240 }
241
242 static int
243 phase34(struct tile_info *info, struct zip_info *zip_info, FILE **in, FILE **reference, int in_count, int with_range)
244 {
245 int i;
246
247 processed_nodes=processed_nodes_out=processed_ways=processed_relations=processed_tiles=0;
248 bytes_read=0;
249 sig_alrm(0);
250 if (! info->write)
251 tile_hash=g_hash_table_new(g_str_hash, g_str_equal);
252 for (i = 0 ; i < in_count ; i++) {
253 if (in[i]) {
254 if (with_range)
255 phase34_process_file_range(info, in[i], reference ? reference[i]:NULL);
256 else
257 phase34_process_file(info, in[i], reference ? reference[i]:NULL);
258 }
259 }
260 if (! info->write)
261 merge_tiles(info);
262 sig_alrm(0);
263 sig_alrm_end();
264 write_tilesdir(info, zip_info, info->tilesdir_out);
265
266 return 0;
267
268 }
269
270
271 void
272 dump(FILE *in)
273 {
274 struct item_bin *ib;
275 while ((ib=read_item(in))) {
276 dump_itembin(ib);
277 }
278 }
279
280 int
281 phase4(FILE **in, int in_count, int with_range, char *suffix, FILE *tilesdir_out, struct zip_info *zip_info)
282 {
283 struct tile_info info;
284 info.write=0;
285 info.maxlen=0;
286 info.suffix=suffix;
287 info.tiles_list=NULL;
288 info.tilesdir_out=tilesdir_out;
289 return phase34(&info, zip_info, in, NULL, in_count, with_range);
290 }
291
292 static int
293 process_slice(FILE **in, FILE **reference, int in_count, int with_range, long long size, char *suffix, struct zip_info *zip_info)
294 {
295 struct tile_head *th;
296 char *slice_data,*zip_data;
297 int zipfiles=0;
298 struct tile_info info;
299 int i;
300
301 slice_data=malloc(size);
302 assert(slice_data != NULL);
303 zip_data=slice_data;
304 th=tile_head_root;
305 while (th) {
306 if (th->process) {
307 th->zip_data=zip_data;
308 zip_data+=th->total_size;
309 }
310 th=th->next;
311 }
312 for (i = 0 ; i < in_count ; i++) {
313 if (in[i])
314 fseek(in[i], 0, SEEK_SET);
315 if (reference && reference[i]) {
316 fseek(reference[i], 0, SEEK_SET);
317 }
318 }
319 info.write=1;
320 info.maxlen=zip_get_maxnamelen(zip_info);
321 info.suffix=suffix;
322 info.tiles_list=NULL;
323 info.tilesdir_out=NULL;
324 phase34(&info, zip_info, in, reference, in_count, with_range);
325
326 th=tile_head_root;
327 while (th) {
328 if (th->process) {
329 if (th->name[0]) {
330 if (th->total_size != th->total_size_used) {
331 fprintf(stderr,"Size error '%s': %d vs %d\n", th->name, th->total_size, th->total_size_used);
332 exit(1);
333 }
334 write_zipmember(zip_info, th->name, zip_get_maxnamelen(zip_info), th->zip_data, th->total_size);
335 zipfiles++;
336 } else
337 fwrite(th->zip_data, th->total_size, 1, zip_get_index(zip_info));
338 }
339 th=th->next;
340 }
341 free(slice_data);
342
343 return zipfiles;
344 }
345
346 int
347 phase5(FILE **in, FILE **references, int in_count, int with_range, char *suffix, struct zip_info *zip_info)
348 {
349 long long size;
350 int slices;
351 int zipnum,written_tiles;
352 struct tile_head *th,*th2;
353 create_tile_hash();
354
355 th=tile_head_root;
356 size=0;
357 slices=0;
358 fprintf(stderr, "Maximum slice size "LONGLONG_FMT"\n", slice_size);
359 while (th) {
360 if (size + th->total_size > slice_size) {
361 fprintf(stderr,"Slice %d is of size "LONGLONG_FMT"\n", slices, size);
362 size=0;
363 slices++;
364 }
365 size+=th->total_size;
366 th=th->next;
367 }
368 if (size)
369 fprintf(stderr,"Slice %d is of size "LONGLONG_FMT"\n", slices, size);
370 th=tile_head_root;
371 size=0;
372 slices=0;
373 while (th) {
374 th2=tile_head_root;
375 while (th2) {
376 th2->process=0;
377 th2=th2->next;
378 }
379 size=0;
380 while (th && size+th->total_size < slice_size) {
381 size+=th->total_size;
382 th->process=1;
383 th=th->next;
384 }
385 /* process_slice() modifies zip_info, but need to retain old info */
386 zipnum=zip_get_zipnum(zip_info);
387 written_tiles=process_slice(in, references, in_count, with_range, size, suffix, zip_info);
388 zip_set_zipnum(zip_info, zipnum+written_tiles);
389 slices++;
390 }
391 return 0;
392 }
393
394 void
395 process_binfile(FILE *in, FILE *out)
396 {
397 struct item_bin *ib;
398 while ((ib=read_item(in))) {
399 fwrite(ib, (ib->len+1)*4, 1, out);
400 }
401 }
402
403 void
404 add_aux_tiles(char *name, struct zip_info *info)
405 {
406 char buffer[4096];
407 char *s;
408 FILE *in;
409 FILE *tmp;
410 in=fopen(name,"rb");
411 if (!in)
412 return;
413 while (fscanf(in,"%s",buffer) == 1) {
414 s=strchr(buffer,'/');
415 if (s)
416 s++;
417 else
418 s=buffer;
419 tmp=fopen(buffer,"rb");
420 if (tmp) {
421 fseek(tmp, 0, SEEK_END);
422 add_aux_tile(info, s, buffer, ftell(tmp));
423 fclose(tmp);
424 }
425 }
426 fclose(in);
427 }

   
Visit the ZANavi Wiki