From: martin-s Date: Sat, 7 Nov 2009 09:08:19 +0000 (+0000) Subject: Fix:maptool:Further cleanups, enabled for building X-Git-Tag: navit-0.5.0.5194svn~2466 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c9bbcde83ce2f39ca175a666642a72983d6dbdd3;p=profile%2Fivi%2Fnavit.git Fix:maptool:Further cleanups, enabled for building git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@2725 ffa7fe5e-494d-0410-b361-a75ebd5db220 --- diff --git a/navit/configure.in b/navit/configure.in index c34491f..970ef5b 100644 --- a/navit/configure.in +++ b/navit/configure.in @@ -807,6 +807,7 @@ navit/map/garmin/Makefile navit/map/poi_geodownload/Makefile navit/map/poi_geodownload/libmdb/Makefile navit/map/poi_geodownload/libmdb/include/Makefile +navit/maptool/Makefile navit/fib-1.1/Makefile navit/font/Makefile navit/font/freetype/Makefile diff --git a/navit/navit/Makefile.am b/navit/navit/Makefile.am index 01968c4..5c2bf0f 100644 --- a/navit/navit/Makefile.am +++ b/navit/navit/Makefile.am @@ -1,27 +1,29 @@ include $(top_srcdir)/Makefile.inc -DIST_SUBDIRS=binding map fib-1.1 font fonts gui graphics osd speech support vehicle xpm maps +DIST_SUBDIRS=binding map maptool fib-1.1 font fonts gui graphics osd speech support vehicle xpm maps SUBDIRS=binding map fib-1.1 font gui graphics osd speech support vehicle xpm -if BUILD_SAMPLEMAP - SUBDIRS += maps -endif if FONTS SUBDIRS += fonts endif -AM_CPPFLAGS = -I$(top_srcdir)/navit/fib-1.1 @NAVIT_CFLAGS@ @ZLIB_CFLAGS@ -DPREFIX=\"@prefix@\" -DLIBDIR=\"@libdir@\" -DMODULE=navit -BUILT_SOURCES = version.h navit_config.h +SUBDIRS+=. +SUBDIRS+=maptool + if BUILD_SAMPLEMAP - BUILT_SOURCES += osm2navit$(EXEEXT) + SUBDIRS += maps endif + +AM_CPPFLAGS = -I$(top_srcdir)/navit/fib-1.1 @NAVIT_CFLAGS@ @ZLIB_CFLAGS@ -DPREFIX=\"@prefix@\" -DLIBDIR=\"@libdir@\" -DMODULE=navit +BUILT_SOURCES = version.h navit_config.h + if SUPPORT_ANDROID lib_LTLIBRARIES = libnavit.la libnavit_la_LDFLAGS = -module -avoid-version @MODULE_LDFLAGS@ -Wl,--no-undefined libnavit_la_LIBADD = @NAVIT_LIBS@ @WORDEXP_LIBS@ @ZLIB_LIBS@ @INTLLIBS@ -Lfib-1.1 -lfib -llog else - bin_PROGRAMS = navit osm2navit + bin_PROGRAMS = navit noinst_LTLIBRARIES = libnavit.la endif @@ -55,8 +57,6 @@ if SUPPORT_ANDROID libnavit_la_SOURCES += android.c navit_SOURCES = navit_LDADD = - osm2navit_SOURCES = - osm2navit_LDADD = android/build.xml: android/AndroidManifest.xml if [ "$(builddir)" != "$(srcdir)" ]; then cp -rp $(srcdir)/android $(builddir)/android; fi @@ -77,9 +77,6 @@ else navit_SOURCES = start.c navit_LDADD = libnavit.la @NAVIT_LIBS@ @WORDEXP_LIBS@ @ZLIB_LIBS@ @INTLLIBS@ -Lfib-1.1 -lfib -osm2navit_CPPFLAGS = $(AM_CPPFLAGS) @ZLIB_CFLAGS@ @POSTGRESQL_CFLAGS@ -osm2navit_SOURCES = osm2navit.c -osm2navit_LDADD = libnavit.la @NAVIT_LIBS@ @ZLIB_LIBS@ @POSTGRESQL_LIBS@ @INTLLIBS@ endif if EVENT_GLIB @@ -89,8 +86,6 @@ endif if !PLUGINS navit_SOURCES += builtin.c navit_LDADD += $(wildcard $(top_builddir)/navit/*/*/*.la) - osm2navit_SOURCES += support-builtin.c - osm2navit_LDADD += $(wildcard $(top_builddir)/navit/support/*/*.la) endif if SUPPORT_WIN32 diff --git a/navit/navit/maps/Makefile.am b/navit/navit/maps/Makefile.am index 28f541a..3b0fba2 100644 --- a/navit/navit/maps/Makefile.am +++ b/navit/navit/maps/Makefile.am @@ -4,7 +4,8 @@ include $(top_srcdir)/Makefile.inc SAMPLE_MAP=osm_bbox_11.3,47.9,11.7,48.2 -osm2navit_args=--attr-debug-level=5 +maptool_args=--attr-debug-level=5 +maptool=$(top_builddir)/navit/maptool/maptool maps_DATA = $(SAMPLE_MAP).bin $(SAMPLE_MAP).xml @@ -14,16 +15,16 @@ samplemap: $(SAMPLE_MAP).bin .osm.bin: echo "Converting osm map" - $(top_builddir)/navit/osm2navit $(osm2navit_args) $@.tmp <$< + $maptool $(maptool_args) $@.tmp <$< mv $@.tmp $@ .txt.bin: - $(top_builddir)/navit/osm2navit $(osm2navit_args) $@.tmp -p ../map/textfile/libmap_textfile.la -m $< + $maptool $(maptool_args) $@.tmp -p ../map/textfile/libmap_textfile.la -m $< mv $@.tmp $@ .osm.bz2.bin: echo "Converting osm map" - bzcat $< | $(top_builddir)/navit/osm2navit $(osm2navit_args) $@.tmp + bzcat $< | $maptool $(maptool_args) $@.tmp mv $@.tmp $@ .bin.xml: diff --git a/navit/navit/maptool/maptool.c b/navit/navit/maptool/maptool.c index 38f34af..171dfbb 100644 --- a/navit/navit/maptool/maptool.c +++ b/navit/navit/maptool/maptool.c @@ -45,7 +45,6 @@ long long slice_size=1024*1024*1024; int attr_debug_level=1; -char *suffix=""; int ignore_unkown = 0; GHashTable *dedupe_ways_hash; int phase; @@ -75,6 +74,14 @@ sig_alrm(int sig) fprintf(stderr,"PROGRESS%d: Processed %d nodes (%d out) %d ways %d relations %d tiles\n", phase, processed_nodes, processed_nodes_out, processed_ways, processed_relations, processed_tiles); } +void +sig_alrm_end(void) +{ +#ifndef _WIN32 + alarm(0); +#endif +} + static struct plugins *plugins; static void add_plugin(char *path) @@ -88,6 +95,14 @@ static void add_plugin(char *path) } static void +maptool_init(void) +{ + if (plugins) + plugins_init(plugins); + osm_init(); +} + +static void usage(FILE *f) { /* DEVELOPPERS : don't forget to update the manpage if you modify theses options */ @@ -113,6 +128,7 @@ usage(FILE *f) fprintf(f,"-z (--compression-level) : set the compression level\n"); exit(1); } + int main(int argc, char **argv) { FILE *ways=NULL,*ways_split=NULL,*ways_split_index=NULL,*nodes=NULL,*turn_restrictions=NULL,*graph=NULL,*coastline=NULL,*tilesdir,*coords,*relations=NULL; @@ -145,6 +161,8 @@ int main(int argc, char **argv) #else char *suffixes[]={""}; #endif + char *suffix=""; + int suffix_count=sizeof(suffixes)/sizeof(char *); int i; main_init(argv[0]); @@ -269,12 +287,9 @@ int main(int argc, char **argv) } if (optind != argc-(output == 1 ? 0:1)) usage(stderr); - if (plugins) - plugins_init(plugins); result=argv[optind]; - build_attrmap(); - build_countrytable(); + maptool_init(); if (input == 0) { if (start == 1) { @@ -289,7 +304,7 @@ int main(int argc, char **argv) fprintf(stderr,"PROGRESS: Phase 1: collecting data\n"); #ifdef HAVE_POSTGRESQL if (dbstr) - phase1_db(dbstr,ways,nodes); + map_collect_data_osm_db(dbstr,ways,nodes); else #endif if (map_handle) { @@ -297,7 +312,7 @@ int main(int argc, char **argv) map_destroy(map_handle); } else - phase1(input_file,ways,nodes,turn_restrictions); + map_collect_data_osm(input_file,ways,nodes,turn_restrictions); if (slices) { fprintf(stderr,"%d slices\n",slices); flush_nodes(1); @@ -340,7 +355,7 @@ int main(int argc, char **argv) coastline=tempfile(suffix,"coastline",1); if (i) load_buffer("coords.tmp",&node_buffer, i*slice_size, slice_size); - phase2(ways,ways_split,ways_split_index,graph,coastline,final); + map_find_intersections(ways,ways_split,ways_split_index,graph,coastline,final); fclose(ways_split); if (ways_split_index) fclose(ways_split_index); @@ -431,101 +446,95 @@ int main(int argc, char **argv) } for (i = 0 ; i < suffix_count ; i++) { suffix=suffixes[i]; - if (start <= 4) { - phase=3; - if (i == 0) { - memset(&zip_info, 0, sizeof(zip_info)); - } - zipnum=zip_info.zipnum; - fprintf(stderr,"PROGRESS: Phase 4: generating tiles %s\n",suffix); - files[0]=NULL; - files[1]=NULL; - files[2]=NULL; - if (process_relations) - files[0]=tempfile(suffix,"relations",0); - if (process_ways) - files[1]=tempfile(suffix,"ways_split",0); - if (process_nodes) - files[2]=tempfile(suffix,"nodes",0); - tilesdir=tempfile(suffix,"tilesdir",1); - phase4(files,3,suffix,tilesdir,&zip_info); - fclose(tilesdir); - if (files[2]) - fclose(files[2]); - if (files[1]) - fclose(files[1]); - if (files[0]) - fclose(files[0]); - zip_info.zipnum=zipnum; - } - if (end == 4) - exit(0); - if (start <= 5) { - phase=4; - fprintf(stderr,"PROGRESS: Phase 5: assembling map %s\n",suffix); - files[0]=NULL; - files[1]=NULL; - files[2]=NULL; - references[0]=NULL; - references[1]=NULL; - references[2]=NULL; - if (process_relations) - files[0]=tempfile(suffix,"relations",0); - if (process_ways) { - files[1]=tempfile(suffix,"ways_split",0); - references[1]=tempfile(suffix,"ways_split_ref",1); - printf("References=%p\n",references[1]); - } - if (process_nodes) - files[2]=tempfile(suffix,"nodes",0); - if (i == 0) { - zip_info.dir_size=0; - zip_info.offset=0; - zip_info.maxnamelen=14+strlen(suffixes[0]); - zip_info.compression_level=compression_level; - zip_info.zipnum=0; - zip_info.dir=tempfile("zipdir","",1); - zip_info.index=tempfile("index","",1); - zip_info.res=fopen(result,"wb+"); - index_init(&zip_info, 1); - } - fprintf(stderr,"Slice %d\n",i); - - phase5(files,references,3,suffix,&zip_info); - for (f = 0 ; f < 3 ; f++) { - if (files[f]) - fclose(files[f]); - if (references[f]) - fclose(references[f]); - } - if(!keep_tmpfiles) { - tempfile_unlink(suffix,"relations"); - tempfile_unlink(suffix,"nodes"); - tempfile_unlink(suffix,"ways_split"); - tempfile_unlink(suffix,"ways_split_ref"); - tempfile_unlink(suffix,"coastline"); - tempfile_unlink(suffix,"turn_restrictions"); - tempfile_unlink(suffix,"graph"); - tempfile_unlink(suffix,"tilesdir"); - tempfile_unlink("zipdir",""); - unlink("coords.tmp"); + if (start <= 4) { + phase=3; + if (i == 0) { + memset(&zip_info, 0, sizeof(zip_info)); + } + zipnum=zip_info.zipnum; + fprintf(stderr,"PROGRESS: Phase 4: generating tiles %s\n",suffix); + for (f = 0 ; f < 3 ; f++) + files[f]=NULL; + if (process_relations) + files[0]=tempfile(suffix,"relations",0); + if (process_ways) + files[1]=tempfile(suffix,"ways_split",0); + if (process_nodes) + files[2]=tempfile(suffix,"nodes",0); + tilesdir=tempfile(suffix,"tilesdir",1); + phase4(files,3,suffix,tilesdir,&zip_info); + fclose(tilesdir); + for (f = 0 ; f < 3 ; f++) { + if (files[f]) + fclose(files[f]); + } + zip_info.zipnum=zipnum; } - if (i == suffix_count-1) { - zipnum=zip_info.zipnum; - write_countrydir(&zip_info); - zip_info.zipnum=zipnum; - write_aux_tiles(&zip_info); - write_index(&zip_info); - phase5_write_directory(&zip_info); - fclose(zip_info.index); - fclose(zip_info.dir); - fclose(zip_info.res); - if (!keep_tmpfiles) { - remove_countryfiles(); - tempfile_unlink("index",""); - } + if (end == 4) + exit(0); + if (start <= 5) { + phase=4; + fprintf(stderr,"PROGRESS: Phase 5: assembling map %s\n",suffix); + for (f = 0 ; f < 3 ; f++) { + files[f]=NULL; + references[f]=NULL; + } + if (process_relations) + files[0]=tempfile(suffix,"relations",0); + if (process_ways) { + files[1]=tempfile(suffix,"ways_split",0); + references[1]=tempfile(suffix,"ways_split_ref",1); + } + if (process_nodes) + files[2]=tempfile(suffix,"nodes",0); + if (i == 0) { + zip_info.dir_size=0; + zip_info.offset=0; + zip_info.maxnamelen=14+strlen(suffixes[0]); + zip_info.compression_level=compression_level; + zip_info.zipnum=0; + zip_info.dir=tempfile("zipdir","",1); + zip_info.index=tempfile("index","",1); + zip_info.res=fopen(result,"wb+"); + index_init(&zip_info, 1); + } + fprintf(stderr,"Slice %d\n",i); + + phase5(files,references,3,suffix,&zip_info); + for (f = 0 ; f < 3 ; f++) { + if (files[f]) + fclose(files[f]); + if (references[f]) + fclose(references[f]); + } + if(!keep_tmpfiles) { + tempfile_unlink(suffix,"relations"); + tempfile_unlink(suffix,"nodes"); + tempfile_unlink(suffix,"ways_split"); + tempfile_unlink(suffix,"ways_split_ref"); + tempfile_unlink(suffix,"coastline"); + tempfile_unlink(suffix,"turn_restrictions"); + tempfile_unlink(suffix,"graph"); + tempfile_unlink(suffix,"tilesdir"); + unlink("coords.tmp"); + } + if (i == suffix_count-1) { + zipnum=zip_info.zipnum; + write_countrydir(&zip_info); + zip_info.zipnum=zipnum; + write_aux_tiles(&zip_info); + zip_write_index(&zip_info); + zip_write_directory(&zip_info); + fclose(zip_info.index); + fclose(zip_info.dir); + fclose(zip_info.res); + if (!keep_tmpfiles) { + remove_countryfiles(); + tempfile_unlink("index",""); + tempfile_unlink("zipdir",""); + } + } } } - } return 0; } diff --git a/navit/navit/maptool/maptool.h b/navit/navit/maptool/maptool.h index 4e9768b..1a792c0 100644 --- a/navit/navit/maptool/maptool.h +++ b/navit/navit/maptool/maptool.h @@ -162,6 +162,7 @@ extern struct item_bin *item_bin; extern int bytes_read; extern int overlap; void sig_alrm(int sig); +void sig_alrm_end(void); /* misc.c */ extern struct rect world_bbox; @@ -171,29 +172,24 @@ void bbox_extend(struct coord *c, struct rect *r); void bbox(struct coord *c, int count, struct rect *r); int contains_bbox(int xl, int yl, int xh, int yh, struct rect *r); void phase1_map(struct map *map, FILE *out_ways, FILE *out_nodes); -void index_init(struct zip_info *info, int version); -void index_submap_add(struct tile_info *info, struct tile_head *th); void dump(FILE *in); int phase4(FILE **in, int in_count, char *suffix, FILE *tilesdir_out, struct zip_info *zip_info); int phase5(FILE **in, FILE **references, int in_count, char *suffix, struct zip_info *zip_info); -int phase5_write_directory(struct zip_info *info); void process_binfile(FILE *in, FILE *out); -void write_index(struct zip_info *info); /* osm.c */ -void build_attrmap(void); -void build_countrytable(void); long long item_bin_get_id(struct item_bin *ib); void flush_nodes(int final); void sort_countries(int keep_tmpfiles); void process_turn_restrictions(FILE *in, FILE *coords, FILE *ways, FILE *ways_index, FILE *out); int resolve_ways(FILE *in, FILE *out); -int phase1(FILE *in, FILE *out_ways, FILE *out_nodes, FILE *out_turn_restrictions); -int phase1_db(char *dbstr, FILE *out_ways, FILE *out_nodes); -int phase2(FILE *in, FILE *out, FILE *out_index, FILE *out_graph, FILE *out_coastline, int final); +int map_collect_data_osm(FILE *in, FILE *out_ways, FILE *out_nodes, FILE *out_turn_restrictions); +int map_collect_data_osm_db(char *dbstr, FILE *out_ways, FILE *out_nodes); +int map_find_intersections(FILE *in, FILE *out, FILE *out_index, FILE *out_graph, FILE *out_coastline, int final); void write_countrydir(struct zip_info *zip_info); void remove_countryfiles(void); +void osm_init(void); /* sourcesink.c */ @@ -237,7 +233,11 @@ int write_aux_tiles(struct zip_info *zip_info); int create_tile_hash(void); void write_tilesdir(struct tile_info *info, struct zip_info *zip_info, FILE *out); void merge_tiles(struct tile_info *info); +void index_init(struct zip_info *info, int version); +void index_submap_add(struct tile_info *info, struct tile_head *th); /* zip.c */ void write_zipmember(struct zip_info *zip_info, char *name, int filelen, char *data, int data_size); +void zip_write_index(struct zip_info *info); +int zip_write_directory(struct zip_info *info); diff --git a/navit/navit/maptool/misc.c b/navit/navit/maptool/misc.c index 0f283a8..1b4ecee 100644 --- a/navit/navit/maptool/misc.c +++ b/navit/navit/maptool/misc.c @@ -80,20 +80,19 @@ bbox(struct coord *c, int count, struct rect *r) int contains_bbox(int xl, int yl, int xh, int yh, struct rect *r) { - if (r->h.x < xl || r->h.x > xh) { - return 0; - } - if (r->l.x > xh || r->l.x < xl) { - return 0; - } - if (r->h.y < yl || r->h.y > yh) { - return 0; - } - if (r->l.y > yh || r->l.y < yl) { - return 0; - } - return 1; - + if (r->h.x < xl || r->h.x > xh) { + return 0; + } + if (r->l.x > xh || r->l.x < xl) { + return 0; + } + if (r->h.y < yl || r->h.y > yh) { + return 0; + } + if (r->l.y > yh || r->l.y < yl) { + return 0; + } + return 1; } void @@ -112,7 +111,7 @@ phase1_map(struct map *map, FILE *out_ways, FILE *out_nodes) while (item_attr_get(item, attr_any, &attr)) { item_bin_add_attr(item_bin, &attr); } - if (item->type >= type_line) + if (item->type >= type_line) item_bin_write(item_bin, out_ways); else item_bin_write(item_bin, out_nodes); @@ -194,39 +193,6 @@ phase34_process_file(struct tile_info *info, FILE *in, FILE *reference) } } -void -index_init(struct zip_info *info, int version) -{ - item_bin_init(item_bin, type_map_information); - item_bin_add_attr_int(item_bin, attr_version, version); - item_bin_write(item_bin, info->index); -} - -void -index_submap_add(struct tile_info *info, struct tile_head *th) -{ - int tlen=tile_len(th->name); - int len=tlen; - char index_tile[len+1+strlen(suffix)]; - struct rect r; - - strcpy(index_tile, th->name); - if (len > 6) - len=6; - else - len=0; - index_tile[len]=0; - if (tlen) - strcat(index_tile, suffix); - tile_bbox(th->name, &r, overlap); - - item_bin_init(item_bin, type_submap); - item_bin_add_coord_rect(item_bin, &r); - item_bin_add_attr_range(item_bin, attr_order, (tlen > 4)?tlen-4 : 0, 255); - item_bin_add_attr_int(item_bin, attr_zipfile_ref, th->zipnum); - tile_write_item_to_tile(info, item_bin, NULL, index_tile); -} - static int phase34(struct tile_info *info, struct zip_info *zip_info, FILE **in, FILE **reference, int in_count) { @@ -244,9 +210,7 @@ phase34(struct tile_info *info, struct zip_info *zip_info, FILE **in, FILE **ref if (! info->write) merge_tiles(info); sig_alrm(0); -#ifndef _WIN32 - alarm(0); -#endif + sig_alrm_end(); write_tilesdir(info, zip_info, info->tilesdir_out); return 0; @@ -329,15 +293,6 @@ process_slice(FILE **in, FILE **reference, int in_count, long long size, char *s return zipfiles; } -static void -cat(FILE *in, FILE *out) -{ - size_t size; - char buffer[4096]; - while ((size=fread(buffer, 1, 4096, in))) - fwrite(buffer, 1, size, out); -} - int phase5(FILE **in, FILE **references, int in_count, char *suffix, struct zip_info *zip_info) { @@ -386,34 +341,6 @@ phase5(FILE **in, FILE **references, int in_count, char *suffix, struct zip_info return 0; } -int -phase5_write_directory(struct zip_info *info) -{ - struct zip_eoc eoc = { - 0x06054b50, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0, - 0x0, - 0x0, - }; - - fseek(info->dir, 0, SEEK_SET); - cat(info->dir, info->res); - eoc.zipenum=info->zipnum; - eoc.zipecenn=info->zipnum; - eoc.zipecsz=info->dir_size; - eoc.zipeofst=info->offset; - fwrite(&eoc, sizeof(eoc), 1, info->res); - sig_alrm(0); -#ifndef _WIN32 - alarm(0); -#endif - return 0; -} - void process_binfile(FILE *in, FILE *out) { @@ -422,15 +349,3 @@ process_binfile(FILE *in, FILE *out) fwrite(ib, (ib->len+1)*4, 1, out); } } - -void -write_index(struct zip_info *info) -{ - int size=ftell(info->index); - char buffer[size]; - - fseek(info->index, 0, SEEK_SET); - fread(buffer, size, 1, info->index); - write_zipmember(info, "index", strlen("index"), buffer, size); - info->zipnum++; -} diff --git a/navit/navit/maptool/osm.c b/navit/navit/maptool/osm.c index d2a30e8..bf6d522 100644 --- a/navit/navit/maptool/osm.c +++ b/navit/navit/maptool/osm.c @@ -507,7 +507,7 @@ build_attrmap_line(char *line) (*attr_mapping_curr)[(*attr_mapping_curr_count)++]=attr_mapping; } -void +static void build_attrmap(void) { char *p,*map=g_strdup(attrmap); @@ -524,7 +524,7 @@ build_attrmap(void) attr_present=g_malloc0(sizeof(*attr_present)*attr_present_count); } -void +static void build_countrytable(void) { int i; @@ -544,9 +544,9 @@ osm_warning(char *type, long long id, int cont, char *fmt, ...) { char str[4096]; va_list ap; - va_start(ap, fmt); - vsnprintf(str, sizeof(str), fmt, ap); - va_end(ap); + va_start(ap, fmt); + vsnprintf(str, sizeof(str), fmt, ap); + va_end(ap); fprintf(stderr,"%shttp://www.openstreetmap.org/browse/%s/%Ld %s",cont ? "":"OSM Warning:",type,id,str); } @@ -1985,7 +1985,7 @@ parse_nd(char *p) } int -phase1(FILE *in, FILE *out_ways, FILE *out_nodes, FILE *out_turn_restrictions) +map_collect_data_osm(FILE *in, FILE *out_ways, FILE *out_nodes, FILE *out_turn_restrictions) { int size=BUFFER_SIZE; char buffer[size]; @@ -2039,15 +2039,13 @@ phase1(FILE *in, FILE *out_ways, FILE *out_nodes, FILE *out_turn_restrictions) } } sig_alrm(0); -#ifndef _WIN32 - alarm(0); -#endif + sig_alrm_end(); return 1; } #ifdef HAVE_POSTGRESQL int -phase1_db(char *dbstr, FILE *out_ways, FILE *out_nodes) +map_collect_data_osm_db(char *dbstr, FILE *out_ways, FILE *out_nodes) { PGconn *conn; PGresult *res,*node,*way,*tag; @@ -2207,9 +2205,7 @@ phase1_db(char *dbstr, FILE *out_ways, FILE *out_nodes) exit(1); } sig_alrm(0); -#ifndef _WIN32 - alarm(0); -#endif + sig_alrm_end(); return 1; } #endif @@ -2255,7 +2251,7 @@ write_item_part(FILE *out, FILE *out_index, FILE *out_graph, struct item_bin *or } int -phase2(FILE *in, FILE *out, FILE *out_index, FILE *out_graph, FILE *out_coastline, int final) +map_find_intersections(FILE *in, FILE *out, FILE *out_index, FILE *out_graph, FILE *out_coastline, int final) { struct coord *c; int i,ccount,last,remaining; @@ -2305,9 +2301,7 @@ phase2(FILE *in, FILE *out, FILE *out_index, FILE *out_graph, FILE *out_coastlin } } sig_alrm(0); -#ifndef _WIN32 - alarm(0); -#endif + sig_alrm_end(); return 0; } @@ -2362,3 +2356,9 @@ remove_countryfiles(void) } } +void osm_init(void) +{ + build_attrmap(); + build_countrytable(); +} + diff --git a/navit/navit/maptool/tile.c b/navit/navit/maptool/tile.c index c527b9c..11f62e1 100644 --- a/navit/navit/maptool/tile.c +++ b/navit/navit/maptool/tile.c @@ -87,25 +87,25 @@ tile(struct rect *r, char *suffix, char *ret, int max, int overlap, struct rect y4=world_bbox.h.y; for (i = 0 ; i < max ; i++) { x2=(x0+x4)/2; - y2=(y0+y4)/2; + y2=(y0+y4)/2; xo=(x4-x0)*overlap/100; yo=(y4-y0)*overlap/100; - if ( contains_bbox(x0,y0,x2+xo,y2+yo,r)) { + if ( contains_bbox(x0,y0,x2+xo,y2+yo,r)) { strcat(ret,"d"); - x4=x2+xo; - y4=y2+yo; - } else if (contains_bbox(x2-xo,y0,x4,y2+yo,r)) { + x4=x2+xo; + y4=y2+yo; + } else if (contains_bbox(x2-xo,y0,x4,y2+yo,r)) { strcat(ret,"c"); - x0=x2-xo; - y4=y2+yo; - } else if (contains_bbox(x0,y2-yo,x2+xo,y4,r)) { + x0=x2-xo; + y4=y2+yo; + } else if (contains_bbox(x0,y2-yo,x2+xo,y4,r)) { strcat(ret,"b"); - x4=x2+xo; - y0=y2-yo; - } else if (contains_bbox(x2-xo,y2-yo,x4,y4,r)) { + x4=x2+xo; + y0=y2-yo; + } else if (contains_bbox(x2-xo,y2-yo,x4,y4,r)) { strcat(ret,"a"); - x0=x2-xo; - y0=y2-yo; + x0=x2-xo; + y0=y2-yo; } else break; } @@ -114,7 +114,7 @@ tile(struct rect *r, char *suffix, char *ret, int max, int overlap, struct rect tr->l.y=y0; tr->h.x=x4; tr->h.y=y4; - } + } if (suffix) strcat(ret,suffix); return i; @@ -400,7 +400,7 @@ add_tile_hash(struct tile_head *th) #endif for( idx = 0; idx < th->num_subtiles; idx++ ) { - data = th_get_subtile( th, idx ); + data = th_get_subtile( th, idx ); if (debug_tile(((char *)data)) || debug_tile(th->name)) { fprintf(stderr,"Parent for '%s' is '%s'\n", *data, th->name); @@ -493,7 +493,7 @@ write_tilesdir(struct tile_info *info, struct zip_info *zip_info, FILE *out) fprintf(out,"%s:%d",(char *)next->data,th->total_size); for ( idx = 0; idx< th->num_subtiles; idx++ ){ - data= th_get_subtile( th, idx ); + data= th_get_subtile( th, idx ); fprintf(out,":%s", *data); } @@ -580,3 +580,36 @@ merge_tiles(struct tile_info *info) fprintf(stderr,"PROGRESS: merged %d tiles\n", work_done); } while (work_done); } + +void +index_init(struct zip_info *info, int version) +{ + item_bin_init(item_bin, type_map_information); + item_bin_add_attr_int(item_bin, attr_version, version); + item_bin_write(item_bin, info->index); +} + +void +index_submap_add(struct tile_info *info, struct tile_head *th) +{ + int tlen=tile_len(th->name); + int len=tlen; + char index_tile[len+1+strlen(info->suffix)]; + struct rect r; + + strcpy(index_tile, th->name); + if (len > 6) + len=6; + else + len=0; + index_tile[len]=0; + if (tlen) + strcat(index_tile, info->suffix); + tile_bbox(th->name, &r, overlap); + + item_bin_init(item_bin, type_submap); + item_bin_add_coord_rect(item_bin, &r); + item_bin_add_attr_range(item_bin, attr_order, (tlen > 4)?tlen-4 : 0, 255); + item_bin_add_attr_int(item_bin, attr_zipfile_ref, th->zipnum); + tile_write_item_to_tile(info, item_bin, NULL, index_tile); +} diff --git a/navit/navit/maptool/zip.c b/navit/navit/maptool/zip.c index bd73452..7bce411 100644 --- a/navit/navit/maptool/zip.c +++ b/navit/navit/maptool/zip.c @@ -23,6 +23,15 @@ #include "maptool.h" #include "zipfile.h" +static void +cat(FILE *in, FILE *out) +{ + size_t size; + char buffer[4096]; + while ((size=fread(buffer, 1, 4096, in))) + fwrite(buffer, 1, size, out); +} + static int compress2_int(Byte *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level) { @@ -140,3 +149,43 @@ write_zipmember(struct zip_info *zip_info, char *name, int filelen, char *data, free(compbuffer); } + +void +zip_write_index(struct zip_info *info) +{ + int size=ftell(info->index); + char buffer[size]; + + fseek(info->index, 0, SEEK_SET); + fread(buffer, size, 1, info->index); + write_zipmember(info, "index", strlen("index"), buffer, size); + info->zipnum++; +} + +int +zip_write_directory(struct zip_info *info) +{ + struct zip_eoc eoc = { + 0x06054b50, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0, + 0x0, + 0x0, + }; + + fseek(info->dir, 0, SEEK_SET); + cat(info->dir, info->res); + eoc.zipenum=info->zipnum; + eoc.zipecenn=info->zipnum; + eoc.zipecsz=info->dir_size; + eoc.zipeofst=info->offset; + fwrite(&eoc, sizeof(eoc), 1, info->res); + sig_alrm(0); +#ifndef _WIN32 + alarm(0); +#endif + return 0; +} diff --git a/navit/navit/osm2navit.c b/navit/navit/osm2navit.c deleted file mode 100644 index c8486a9..0000000 --- a/navit/navit/osm2navit.c +++ /dev/null @@ -1,5581 +0,0 @@ -/** - * Navit, a modular navigation system. - * Copyright (C) 2005-2008 Navit Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - - -#define _FILE_OFFSET_BITS 64 -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "file.h" -#include "item.h" -#include "map.h" -#include "zipfile.h" -#include "main.h" -#include "config.h" -#include "linguistics.h" -#include "plugin.h" -#ifdef HAVE_POSTGRESQL -#include -#endif - -#define BUFFER_SIZE 1280 - -typedef long int osmid; - - -#if 1 -#define debug_tile(x) 0 -#else -#define debug_tile(x) (!strcmp(x,"bcdbd") || !strcmp(x,"bcdbd") || !strcmp(x,"bcdbda") || !strcmp(x,"bcdbdb") || !strcmp(x,"bcdbdba") || !strcmp(x,"bcdbdbb") || !strcmp(x,"bcdbdbba") || !strcmp(x,"bcdbdbaa") || !strcmp(x,"bcdbdbacaa") || !strcmp(x,"bcdbdbacab") || !strcmp(x,"bcdbdbacaba") || !strcmp(x,"bcdbdbacabaa") || !strcmp(x,"bcdbdbacabab") || !strcmp(x,"bcdbdbacababb") || !strcmp(x,"bcdbdbacababba") || !strcmp(x,"bcdbdbacababbb") || !strcmp(x,"bcdbdbacababbd") || !strcmp(x,"bcdbdbacababaa") || !strcmp(x,"bcdbdbacababab") || !strcmp(x,"bcdbdbacababac") || !strcmp(x,"bcdbdbacababad") || !strcmp(x,"bcdbdbacabaaa") || !strcmp(x,"bcdbdbacabaaba") || !strcmp(x,"bcdbdbacabaabb") || !strcmp(x,"bcdbdbacabaabc") || !strcmp(x,"bcdbdbacabaabd") || !strcmp(x,"bcdbdbacabaaaa") || !strcmp(x,"bcdbdbacabaaab") || !strcmp(x,"bcdbdbacabaaac") || !strcmp(x,"bcdbdbacabaaad") || 0) -#endif - -#if 1 -#define debug_itembin(ib) 0 -#else -#define debug_itembin(ib) ((ib)->type == 0x80000071 && (ib)->len == 8 && ((struct coord *)((ib)+1))->x == 0xfffbe05f) -#endif - -static GHashTable *dedupe_ways_hash; - -static int attr_debug_level=1; -static int nodeid,wayid; -static int phase; -static int ignore_unkown = 0, coverage=0; - -long long slice_size=1024*1024*1024; -long long current_id; -int slices; - -char *osm_types[]={"unknown","node","way","relation"}; - -static char *attrmap={ - "n *=* point_unkn\n" - "n Annehmlichkeit=Hochsitz poi_hunting_stand\n" - "n addr:housenumber=* house_number\n" - "n aeroway=aerodrome poi_airport\n" - "n aeroway=airport poi_airport\n" - "n aeroway=helipad poi_heliport\n" - "n aeroway=terminal poi_airport\n" - "n amenity=atm poi_bank\n" - "n amenity=bank poi_bank\n" - "n amenity=bench poi_bench\n" - "n amenity=biergarten poi_biergarten\n" - "n amenity=bus_station poi_bus_station\n" - "n amenity=cafe poi_cafe\n" - "n amenity=cinema poi_cinema\n" - "n amenity=college poi_school_college\n" - "n amenity=courthouse poi_justice\n" - "n amenity=drinking_water poi_potable_water\n" - "n amenity=fast_food poi_fastfood\n" - "n amenity=fire_station poi_firebrigade\n" - "n amenity=fountain poi_fountain\n" - "n amenity=fuel poi_fuel\n" - "n amenity=grave_yard poi_cemetery\n" - "n amenity=hospital poi_hospital\n" - "n amenity=hunting_stand poi_hunting_stand\n" - "n amenity=kindergarten poi_kindergarten\n" - "n amenity=library poi_library\n" - "n amenity=nightclub poi_nightclub\n" - "n amenity=park_bench poi_bench\n" - "n amenity=parking poi_car_parking\n" - "n amenity=pharmacy poi_pharmacy\n" - "n amenity=place_of_worship,religion=christian poi_church\n" - "n amenity=police poi_police\n" - "n amenity=post_box poi_post_box\n" - "n amenity=post_office poi_post_office\n" - "n amenity=prison poi_prison\n" - "n amenity=pub poi_bar\n" - "n amenity=public_building poi_public_office\n" - "n amenity=recycling poi_recycling\n" - "n amenity=restaurant poi_restaurant\n" - "n amenity=school poi_school\n" - "n amenity=shelter poi_shelter\n" - "n amenity=taxi poi_taxi\n" - "n amenity=tec_common tec_common\n" - "n amenity=telephone poi_telephone\n" - "n amenity=theatre poi_theater\n" - "n amenity=toilets poi_restroom\n" - "n amenity=toilets poi_toilets\n" - "n amenity=townhall poi_townhall\n" - "n amenity=university poi_school_university\n" - "n amenity=vending_machine poi_vending_machine\n" - "n barrier=bollard barrier_bollard\n" - "n barrier=cycle_barrier barrier_cycle\n" - "n barrier=lift_gate barrier_lift_gate\n" - "n car=car_rental poi_car_rent\n" - "n highway=bus_station poi_bus_station\n" - "n highway=bus_stop poi_bus_stop\n" - "n highway=mini_roundabout mini_roundabout\n" - "n highway=motorway_junction highway_exit\n" - "n highway=stop traffic_sign_stop\n" - "n highway=traffic_signals traffic_signals\n" - "n highway=turning_circle turning_circle\n" - "n historic=boundary_stone poi_boundary_stone\n" - "n historic=castle poi_castle\n" - "n historic=memorial poi_memorial\n" - "n historic=monument poi_monument\n" - "n historic=* poi_ruins\n" - "n landuse=cemetery poi_cemetery\n" - "n leisure=fishing poi_fish\n" - "n leisure=golf_course poi_golf\n" - "n leisure=marina poi_marine\n" - "n leisure=playground poi_playground\n" - "n leisure=slipway poi_boat_ramp\n" - "n leisure=sports_centre poi_sport\n" - "n leisure=stadium poi_stadium\n" - "n man_made=tower poi_tower\n" - "n military=airfield poi_military\n" - "n military=barracks poi_military\n" - "n military=bunker poi_military\n" - "n military=danger_area poi_danger_area\n" - "n military=range poi_military\n" - "n natural=bay poi_bay\n" - "n natural=peak poi_peak\n" - "n natural=tree poi_tree\n" - "n place=city town_label_2e5\n" - "n place=hamlet town_label_2e2\n" - "n place=locality town_label_2e0\n" - "n place=suburb district_label\n" - "n place=town town_label_2e4\n" - "n place=village town_label_2e3\n" - "n power=tower power_tower\n" - "n power=sub_station power_substation\n" - "n railway=halt poi_rail_halt\n" - "n railway=level_crossing poi_level_crossing\n" - "n railway=station poi_rail_station\n" - "n railway=tram_stop poi_rail_tram_stop\n" - "n shop=baker poi_shop_baker\n" - "n shop=bakery poi_shop_baker\n" - "n shop=beverages poi_shop_beverages\n" - "n shop=bicycle poi_shop_bicycle\n" - "n shop=butcher poi_shop_butcher\n" - "n shop=car poi_car_dealer_parts\n" - "n shop=car_repair poi_repair_service\n" - "n shop=clothes poi_shop_apparel\n" - "n shop=convenience poi_shop_grocery\n" - "n shop=drogist poi_shop_drugstore\n" - "n shop=florist poi_shop_florist\n" - "n shop=fruit poi_shop_fruit\n" - "n shop=furniture poi_shop_furniture\n" - "n shop=garden_centre poi_shop_handg\n" - "n shop=hardware poi_shop_handg\n" - "n shop=hairdresser poi_hairdresser\n" - "n shop=kiosk poi_shop_kiosk\n" - "n shop=optician poi_shop_optician\n" - "n shop=parfum poi_shop_parfum\n" - "n shop=photo poi_shop_photo\n" - "n shop=shoes poi_shop_shoes\n" - "n shop=supermarket poi_shopping\n" - "n sport=baseball poi_baseball\n" - "n sport=basketball poi_basketball\n" - "n sport=climbing poi_climbing\n" - "n sport=golf poi_golf\n" - "n sport=motor_sports poi_motor_sport\n" - "n sport=skiing poi_skiing\n" - "n sport=soccer poi_soccer\n" - "n sport=stadium poi_stadium\n" - "n sport=swimming poi_swimming\n" - "n sport=tennis poi_tennis\n" - "n tourism=attraction poi_attraction\n" - "n tourism=camp_site poi_camp_rv\n" - "n tourism=caravan_site poi_camp_rv\n" - "n tourism=guest_house poi_guesthouse\n" - "n tourism=hostel poi_hostel\n" - "n tourism=hotel poi_hotel\n" - "n tourism=information poi_information\n" - "n tourism=motel poi_motel\n" - "n tourism=museum poi_museum_history\n" - "n tourism=picnic_site poi_picnic\n" - "n tourism=theme_park poi_resort\n" - "n tourism=viewpoint poi_viewpoint\n" - "n tourism=zoo poi_zoo\n" - "n traffic_sign=city_limit traffic_sign_city_limit\n" - "w *=* street_unkn\n" - "w addr:interpolation=even house_number_interpolation_even\n" - "w addr:interpolation=odd house_number_interpolation_odd\n" - "w addr:interpolation=all house_number_interpolation_all\n" - "w addr:interpolation=alphabetic house_number_interpolation_alphabetic\n" - "w aerialway=cable_car lift_cable_car\n" - "w aerialway=chair_lift lift_chair\n" - "w aerialway=drag_lift lift_drag\n" - "w aeroway=aerodrome poly_airport\n" - "w aeroway=apron poly_apron\n" - "w aeroway=runway aeroway_runway\n" - "w aeroway=taxiway aeroway_taxiway\n" - "w aeroway=terminal poly_terminal\n" - "w amenity=college poly_college\n" - "w amenity=grave_yard poly_cemetery\n" - "w amenity=parking poly_car_parking\n" - "w amenity=place_of_worship poly_building\n" - "w amenity=university poly_university\n" - "w boundary=administrative border_country\n" - "w boundary=civil border_civil\n" - "w boundary=national_park border_national_park\n" - "w boundary=political border_political\n" - "w building=* poly_building\n" - "w contour_ext=elevation_major height_line_1\n" - "w contour_ext=elevation_medium height_line_2\n" - "w contour_ext=elevation_minor height_line_3\n" -#if 0 /* FIXME: Implement this as attribute */ - "w cycleway=track cycleway\n" -#endif - "w highway=bridleway bridleway\n" - "w highway=bus_guideway bus_guideway\n" - "w highway=construction street_construction\n" - "w highway=cyclepath cycleway\n" - "w highway=cycleway cycleway\n" - "w highway=footway footway\n" - "w highway=footway,piste:type=nordic footway_and_piste_nordic\n" - "w highway=living_street living_street\n" - "w highway=minor street_1_land\n" - "w highway=parking_lane street_parking_lane\n" - "w highway=path path\n" - "w highway=path,bicycle=designated cycleway\n" - "w highway=path,foot=designated footway\n" - "w highway=path,horse=designated bridleway\n" - "w highway=path,sac_scale=alpine_hiking hiking_alpine\n" - "w highway=path,sac_scale=demanding_alpine_hiking hiking_alpine_demanding\n" - "w highway=path,sac_scale=demanding_mountain_hiking hiking_mountain_demanding\n" - "w highway=path,sac_scale=difficult_alpine_hiking hiking_alpine_difficult\n" - "w highway=path,sac_scale=hiking hiking\n" - "w highway=path,sac_scale=mountain_hiking hiking_mountain\n" - "w highway=pedestrian street_pedestrian\n" - "w highway=pedestrian,area=1 poly_pedestrian\n" - "w highway=plaza poly_plaza\n" - "w highway=motorway highway_land\n" - "w highway=motorway,rural=0 highway_city\n" - "w highway=motorway_link ramp\n" - "w highway=trunk street_4_land\n" - "w highway=trunk,name=*,rural=1 street_4_land\n" - "w highway=trunk,name=* street_4_city\n" - "w highway=trunk,rural=0 street_4_city\n" - "w highway=trunk_link ramp\n" - "w highway=primary street_4_land\n" - "w highway=primary,name=*,rural=1 street_4_land\n" - "w highway=primary,name=* street_4_city\n" - "w highway=primary,rural=0 street_4_city\n" - "w highway=primary_link ramp\n" - "w highway=secondary street_3_land\n" - "w highway=secondary,name=*,rural=1 street_3_land\n" - "w highway=secondary,name=* street_3_city\n" - "w highway=secondary,rural=0 street_3_city\n" - "w highway=secondary,area=1 poly_street_3\n" - "w highway=secondary_link ramp\n" - "w highway=tertiary street_2_land\n" - "w highway=tertiary,name=*,rural=1 street_2_land\n" - "w highway=tertiary,name=* street_2_city\n" - "w highway=tertiary,rural=0 street_2_city\n" - "w highway=tertiary,area=1 poly_street_2\n" - "w highway=tertiary_link ramp\n" - "w highway=residential street_1_city\n" - "w highway=residential,area=1 poly_street_1\n" - "w highway=unclassified street_1_city\n" - "w highway=unclassified,area=1 poly_street_1\n" - "w highway=road street_1_city\n" - "w highway=service street_service\n" - "w highway=service,area=1 poly_service\n" - "w highway=service,service=parking_aisle street_parking_lane\n" - "w highway=track track_gravelled\n" - "w highway=track,surface=grass track_grass\n" - "w highway=track,surface=gravel track_gravelled\n" - "w highway=track,surface=ground track_ground\n" - "w highway=track,surface=paved track_paved\n" - "w highway=track,surface=unpaved track_unpaved\n" - "w highway=track,tracktype=grade1 track_paved\n" - "w highway=track,tracktype=grade2 track_gravelled\n" - "w highway=track,tracktype=grade3 track_unpaved\n" - "w highway=track,tracktype=grade4 track_ground\n" - "w highway=track,tracktype=grade5 track_grass\n" - "w highway=unsurfaced track_gravelled\n" - "w highway=steps steps\n" - "w historic=archaeological_site poly_archaeological_site\n" - "w historic=battlefield poly_battlefield\n" - "w historic=ruins poly_ruins\n" - "w historic=town gate poly_building\n" - "w landuse=allotments poly_allotments\n" - "w landuse=basin poly_basin\n" - "w landuse=brownfield poly_brownfield\n" - "w landuse=cemetery poly_cemetery\n" - "w landuse=commercial poly_commercial\n" - "w landuse=construction poly_construction\n" - "w landuse=farm poly_farm\n" - "w landuse=farmland poly_farm\n" - "w landuse=farmyard poly_town\n" - "w landuse=forest poly_wood\n" - "w landuse=greenfield poly_greenfield\n" - "w landuse=industrial poly_industry\n" - "w landuse=landfill poly_landfill\n" - "w landuse=military poly_military\n" - "w landuse=plaza poly_plaza\n" - "w landuse=quarry poly_quarry\n" - "w landuse=railway poly_railway\n" - "w landuse=recreation_ground poly_recreation_ground\n" - "w landuse=reservoir poly_reservoir\n" - "w landuse=residential poly_town\n" - "w landuse=residential,area=1 poly_town\n" - "w landuse=retail poly_retail\n" - "w landuse=village_green poly_village_green\n" - "w landuse=vineyard poly_farm\n" - "w leisure=common poly_common\n" - "w leisure=fishing poly_fishing\n" - "w leisure=garden poly_garden\n" - "w leisure=golf_course poly_golf_course\n" - "w leisure=marina poly_marina\n" - "w leisure=nature_reserve poly_nature_reserve\n" - "w leisure=park poly_park\n" - "w leisure=pitch poly_sports_pitch\n" - "w leisure=playground poly_playground\n" - "w leisure=sports_centre poly_sport\n" - "w leisure=stadium poly_sports_stadium\n" - "w leisure=track poly_sports_track\n" - "w leisure=water_park poly_water_park\n" - "w military=airfield poly_airfield\n" - "w military=barracks poly_barracks\n" - "w military=danger_area poly_danger_area\n" - "w military=naval_base poly_naval_base\n" - "w military=range poly_range\n" - "w natural=beach poly_beach\n" - "w natural=coastline water_line\n" - "w natural=fell poly_fell\n" - "w natural=glacier poly_glacier\n" - "w natural=heath poly_heath\n" - "w natural=land poly_land\n" - "w natural=marsh poly_marsh\n" - "w natural=mud poly_mud\n" - "w natural=scree poly_scree\n" - "w natural=scrub poly_scrub\n" - "w natural=water poly_water\n" - "w natural=wood poly_wood\n" - "w piste:type=downhill,piste:difficulty=advanced piste_downhill_advanced\n" - "w piste:type=downhill,piste:difficulty=easy piste_downhill_easy\n" - "w piste:type=downhill,piste:difficulty=expert piste_downhill_expert\n" - "w piste:type=downhill,piste:difficulty=freeride piste_downhill_freeride\n" - "w piste:type=downhill,piste:difficulty=intermediate piste_downhill_intermediate\n" - "w piste:type=downhill,piste:difficulty=novice piste_downhill_novice\n" - "w piste:type=nordic piste_nordic\n" - "w place=suburb poly_place1\n" - "w place=hamlet poly_place2\n" - "w place=village poly_place3\n" - "w place=municipality poly_place4\n" - "w place=town poly_place5\n" - "w place=city poly_place6\n" - "w power=line powerline\n" - "w railway=abandoned rail_abandoned\n" - "w railway=disused rail_disused\n" - "w railway=light_rail rail_light\n" - "w railway=monorail rail_mono\n" - "w railway=narrow_gauge rail_narrow_gauge\n" - "w railway=preserved rail_preserved\n" - "w railway=rail rail\n" - "w railway=subway rail_subway\n" - "w railway=tram rail_tram\n" - "w route=ferry ferry\n" - "w route=ski piste_nordic\n" - "w sport=* poly_sport\n" - "w tourism=artwork poly_artwork\n" - "w tourism=attraction poly_attraction\n" - "w tourism=camp_site poly_camp_site\n" - "w tourism=caravan_site poly_caravan_site\n" - "w tourism=picnic_site poly_picnic_site\n" - "w tourism=theme_park poly_theme_park\n" - "w tourism=zoo poly_zoo\n" - "w waterway=canal water_canal\n" - "w waterway=drain water_drain\n" - "w waterway=river water_river\n" - "w waterway=riverbank poly_water\n" - "w waterway=stream water_stream\n" - "w barrier=ditch ditch\n" - "w barrier=hedge hedge\n" - "w barrier=fence fence\n" - "w barrier=wall wall\n" - "w barrier=retaining_wall retaining_wall\n" - "w barrier=city_wall city_wall\n" -}; - - -static char buffer[400000]; -static struct item_bin *item_bin=(struct item_bin *)(void *)buffer; - -struct coord coord_buffer[65536]; - -char *suffix=""; - -#define IS_REF(c) ((c).x >= (1 << 30)) -#define REF(c) ((c).y) -#define SET_REF(c,ref) do { (c).x = 1 << 30; (c).y = ref ; } while(0) - -struct rect { - struct coord l,h; -}; - -static void bbox_extend(struct coord *c, struct rect *r); - -GList *aux_tile_list; - -struct country_table { - int countryid; - char *names; - FILE *file; - int size; - struct rect r; -} country_table[] = { - { 36,"Australia,AUS"}, - { 40,"Austria,Österreich,AUT"}, - { 56,"Belgium"}, - {124,"Canada"}, - {152,"Chile"}, - {191,"Croatia,Republika Hrvatska,HR"}, - {203,"Czech Republic,Česká republika,CZ"}, - {208,"Denmark,Danmark,DK"}, - {246,"Finland,Suomi"}, - {250,"France,République française,FR"}, - {276,"Germany,Deutschland,Bundesrepublik Deutschland"}, - {348,"Hungary"}, - {380,"Italy,Italia"}, - {442,"Luxembourg"}, - {528,"Nederland,The Netherlands,Niederlande,NL"}, - {578,"Norway,Norge,Noreg,NO"}, - {616,"Poland,Polska,PL"}, - {642,"România,Romania,RO"}, - {643,"Россия,Российская Федерация,Russia,Russian Federation"}, - {703,"Slovakia,Slovensko,SK"}, - {705,"Slovenia,Republika Slovenija,SI"}, - {724,"Spain,Espana,España,Reino de Espana"}, - {752,"Sweden,Sverige,Konungariket Sverige,SE"}, - {756,"Schweiz"}, - {826,"United Kingdom,UK"}, - {840,"USA"}, - {999,"Unknown"}, -}; - -static GHashTable *country_table_hash; - -struct attr_mapping { - enum item_type type; - int attr_present_idx_count; - int attr_present_idx[0]; -}; - -static struct attr_mapping **attr_mapping_node; -static int attr_mapping_node_count; -static struct attr_mapping **attr_mapping_way; -static int attr_mapping_way_count; - -static char *attr_present; -static int attr_present_count; -static GHashTable *attr_hash; - - -static GHashTable *strings_hash = NULL; - -static void dump_itembin(struct item_bin *ib); - -static void -osm_warning(char *type, long long id, int cont, char *fmt, ...) -{ - char str[4096]; - va_list ap; - va_start(ap, fmt); - vsnprintf(str, sizeof(str), fmt, ap); - va_end(ap); - fprintf(stderr,"%shttp://www.openstreetmap.org/browse/%s/%Ld %s",cont ? "":"OSM Warning:",type,id,str); -} - -static char* string_hash_lookup( const char* key ) -{ - char* key_ptr = NULL; - - if ( strings_hash == NULL ) { - strings_hash = g_hash_table_new(g_str_hash, g_str_equal); - } - - if ( ( key_ptr = g_hash_table_lookup(strings_hash, key )) == NULL ) { - key_ptr = g_strdup( key ); - g_hash_table_insert(strings_hash, key_ptr, (gpointer)key_ptr ); - - } - return key_ptr; -} - -static void -build_attrmap_line(char *line) -{ - char *t=NULL,*kvl=NULL,*i=NULL,*p,*kv; - struct attr_mapping ***attr_mapping_curr,*attr_mapping=g_malloc0(sizeof(struct attr_mapping)); - int idx,attr_mapping_count=0,*attr_mapping_curr_count; - t=line; - p=strchr(t,'\t'); - if (p) { - while (*p == '\t') - *p++='\0'; - kvl=p; - p=strchr(kvl,'\t'); - } - if (p) { - while (*p == '\t') - *p++='\0'; - i=p; - } - if (t[0] == 'w') { - if (! i) - i="street_unkn"; - attr_mapping_curr=&attr_mapping_way; - attr_mapping_curr_count=&attr_mapping_way_count; - } else { - if (! i) - i="point_unkn"; - attr_mapping_curr=&attr_mapping_node; - attr_mapping_curr_count=&attr_mapping_node_count; - } - attr_mapping->type=item_from_name(i); - while ((kv=strtok(kvl, ","))) { - kvl=NULL; - if (!(idx=(int)(long)g_hash_table_lookup(attr_hash, kv))) { - idx=attr_present_count++; - g_hash_table_insert(attr_hash, kv, (gpointer)(long)idx); - } - attr_mapping=g_realloc(attr_mapping, sizeof(struct attr_mapping)+(attr_mapping_count+1)*sizeof(int)); - attr_mapping->attr_present_idx[attr_mapping_count++]=idx; - attr_mapping->attr_present_idx_count=attr_mapping_count; - } - *attr_mapping_curr=g_realloc(*attr_mapping_curr, sizeof(**attr_mapping_curr)*(*attr_mapping_curr_count+1)); - (*attr_mapping_curr)[(*attr_mapping_curr_count)++]=attr_mapping; -} - -static void -build_attrmap(char *map) -{ - char *p; - attr_hash=g_hash_table_new(g_str_hash, g_str_equal); - attr_present_count=1; - while (map) { - p=strchr(map,'\n'); - if (p) - *p++='\0'; - if (strlen(map)) - build_attrmap_line(map); - map=p; - } - attr_present=g_malloc0(sizeof(*attr_present)*attr_present_count); -} - -static void -build_countrytable(void) -{ - int i; - char *names,*str,*tok; - country_table_hash=g_hash_table_new(g_str_hash, g_str_equal); - for (i = 0 ; i < sizeof(country_table)/sizeof(struct country_table) ; i++) { - names=g_strdup(country_table[i].names); - str=names; - while ((tok=strtok(str, ","))) { - str=NULL; - g_hash_table_insert(country_table_hash, tok, (gpointer)&country_table[i]); - } - } -} - - - -static int processed_nodes, processed_nodes_out, processed_ways, processed_relations, processed_tiles; -static int in_way, in_node, in_relation; - -static void -sig_alrm(int sig) -{ -#ifndef _WIN32 - signal(SIGALRM, sig_alrm); - alarm(30); -#endif - fprintf(stderr,"PROGRESS%d: Processed %d nodes (%d out) %d ways %d relations %d tiles\n", phase, processed_nodes, processed_nodes_out, processed_ways, processed_relations, processed_tiles); -} - -struct tile_data { - char buffer[1024]; - int tile_depth; - struct rect item_bbox; - struct rect tile_bbox; -}; - -struct item_bin_sink_func { - int (*func)(struct item_bin_sink_func *func, struct item_bin *ib, struct tile_data *tile_data); - void *priv_data[8]; -}; - -struct item_bin_sink { - void *priv_data[8]; - GList *sink_funcs; -}; - -struct item_bin { - int len; - enum item_type type; - int clen; -} item; - -struct attr_bin { - int len; - enum attr_type type; -}; - -int maxspeed_attr_value; - -char debug_attr_buffer[BUFFER_SIZE]; - -int flags[4]; - -int flags_attr_value; - -struct attr_bin osmid_attr; -long int osmid_attr_value; - -char is_in_buffer[BUFFER_SIZE]; - -char attr_strings_buffer[BUFFER_SIZE*16]; -int attr_strings_buffer_len; - -enum attr_strings { - attr_string_phone, - attr_string_fax, - attr_string_email, - attr_string_url, - attr_string_street_name, - attr_string_street_name_systematic, - attr_string_house_number, - attr_string_label, - attr_string_postal, - attr_string_population, - attr_string_last, -}; - -char *attr_strings[attr_string_last]; - -struct tile_parameter { - int min; - int max; - int overlap; -}; - - - -static struct item_bin_sink * -item_bin_sink_new(void) -{ - struct item_bin_sink *ret=g_new0(struct item_bin_sink, 1); - - return ret; -} - -static struct item_bin_sink_func * -item_bin_sink_func_new(int (*func)(struct item_bin_sink_func *func, struct item_bin *ib, struct tile_data *tile_data)) -{ - struct item_bin_sink_func *ret=g_new0(struct item_bin_sink_func, 1); - ret->func=func; - return ret; -} - -static void -item_bin_sink_func_destroy(struct item_bin_sink_func *func) -{ - g_free(func); -} - -static void -item_bin_sink_add_func(struct item_bin_sink *sink, struct item_bin_sink_func *func) -{ - sink->sink_funcs=g_list_append(sink->sink_funcs, func); -} - -static void -item_bin_sink_destroy(struct item_bin_sink *sink) -{ - /* g_list_foreach(sink->sink_funcs, (GFunc)g_free, NULL); */ - g_list_free(sink->sink_funcs); - g_free(sink); -} - -static void -attr_strings_clear(void) -{ - attr_strings_buffer_len=0; - memset(attr_strings, 0, sizeof(attr_strings)); -} - -static void -attr_strings_save(enum attr_strings id, char *str) -{ - attr_strings[id]=attr_strings_buffer+attr_strings_buffer_len; - strcpy(attr_strings[id], str); - attr_strings_buffer_len+=strlen(str)+1; -} - -static void -item_bin_set_type(struct item_bin *ib, enum item_type type) -{ - ib->type=type; -} - -static void -item_bin_init(struct item_bin *ib, enum item_type type) -{ - ib->clen=0; - ib->len=2; - item_bin_set_type(ib, type); -} - - -static void -item_bin_add_coord(struct item_bin *ib, struct coord *c, int count) -{ - struct coord *c2=(struct coord *)(ib+1); - c2+=ib->clen/2; - memcpy(c2, c, count*sizeof(struct coord)); - ib->clen+=count*2; - ib->len+=count*2; -} - -static void -item_bin_copy_coord(struct item_bin *ib, struct item_bin *from, int dir) -{ - struct coord *c=(struct coord *)(from+1); - int i,count=from->clen/2; - if (dir >= 0) { - item_bin_add_coord(ib, c, count); - return; - } - for (i = 1 ; i <= count ; i++) - item_bin_add_coord(ib, &c[count-i], 1); -} - -static void -item_bin_add_coord_rect(struct item_bin *ib, struct rect *r) -{ - item_bin_add_coord(ib, &r->l, 1); - item_bin_add_coord(ib, &r->h, 1); -} - -static void -item_bin_add_attr(struct item_bin *ib, struct attr *attr) -{ - struct attr_bin *ab=(struct attr_bin *)((int *)ib+ib->len+1); - int size=attr_data_size(attr); - int pad=(4-(size%4))%4; - ab->type=attr->type; - memcpy(ab+1, attr_data_get(attr), size); - memset((unsigned char *)(ab+1)+size, 0, pad); - ab->len=(size+pad)/4+1; - ib->len+=ab->len+1; -} - -static void -item_bin_add_attr_int(struct item_bin *ib, enum attr_type type, int val) -{ - struct attr attr; - attr.type=type; - attr.u.num=val; - item_bin_add_attr(ib, &attr); -} - -static void * -item_bin_get_attr(struct item_bin *ib, enum attr_type type, void *last) -{ - unsigned char *s=(unsigned char *)ib; - unsigned char *e=s+(ib->len+1)*4; - s+=sizeof(struct item_bin)+ib->clen*4; - while (s < e) { - struct attr_bin *ab=(struct attr_bin *)s; - s+=(ab->len+1)*4; - if (ab->type == type && (void *)(ab+1) > last) { - return (ab+1); - } - } - return NULL; -} - -static long long -item_bin_get_nodeid(struct item_bin *ib) -{ - long long *ret=item_bin_get_attr(ib, attr_osm_nodeid, NULL); - if (ret) - return *ret; - return 0; -} - -static long long -item_bin_get_wayid(struct item_bin *ib) -{ - long long *ret=item_bin_get_attr(ib, attr_osm_wayid, NULL); - if (ret) - return *ret; - return 0; -} - -static long long -item_bin_get_relationid(struct item_bin *ib) -{ - long long *ret=item_bin_get_attr(ib, attr_osm_relationid, NULL); - if (ret) - return *ret; - return 0; -} - -static long long -item_bin_get_id(struct item_bin *ib) -{ - long long ret; - if (ib->type < 0x80000000) - return item_bin_get_nodeid(ib); - ret=item_bin_get_wayid(ib); - if (!ret) - ret=item_bin_get_relationid(ib); - return ret; -} - -static void -item_bin_add_attr_longlong(struct item_bin *ib, enum attr_type type, long long val) -{ - struct attr attr; - attr.type=type; - attr.u.num64=&val; - item_bin_add_attr(ib, &attr); -} - -static void -item_bin_add_attr_string(struct item_bin *ib, enum attr_type type, char *str) -{ - struct attr attr; - if (! str) - return; - attr.type=type; - attr.u.str=str; - item_bin_add_attr(ib, &attr); -} - -static void -item_bin_add_attr_range(struct item_bin *ib, enum attr_type type, short min, short max) -{ - struct attr attr; - attr.type=type; - attr.u.range.min=min; - attr.u.range.max=max; - item_bin_add_attr(ib, &attr); -} - -static void -item_bin_write(struct item_bin *ib, FILE *out) -{ - fwrite(ib, (ib->len+1)*4, 1, out); -} - -static int -item_bin_write_to_sink(struct item_bin *ib, struct item_bin_sink *sink, struct tile_data *tile_data) -{ - GList *list=sink->sink_funcs; - int ret=0; - while (list) { - struct item_bin_sink_func *func=list->data; - ret=func->func(func, ib, tile_data); - if (ret) - break; - list=g_list_next(list); - } - return ret; -} - -static int -item_bin_write_to_sink_func(struct item_bin *ib, struct item_bin_sink_func *func, struct tile_data *tile_data) -{ - return func->func(func, ib, tile_data); -} - -static int -item_bin_write_debug_point_to_sink(struct item_bin_sink *sink, struct coord *c, const char *fmt, ...) -{ - char buffer[16384]; - char buffer2[16384]; - va_list ap; - struct item_bin *ib=(struct item_bin *)buffer; - - item_bin_init(ib, type_town_label_1e7); - item_bin_add_coord(ib, c, 1); - va_start(ap, fmt); - vsprintf(buffer2,fmt,ap); - va_end(ap); - item_bin_add_attr_string(ib, attr_label, buffer2); - return item_bin_write_to_sink(ib, sink, NULL); -} - -static char * -coord_to_str(struct coord *c) -{ - int x=c->x; - int y=c->y; - char *sx=""; - char *sy=""; - if (x < 0) { - sx="-"; - x=-x; - } - if (y < 0) { - sy="-"; - y=-y; - } - return g_strdup_printf("%s0x%x %s0x%x",sx,x,sy,y); -} - -static void -dump_coord(struct coord *c, FILE *out) -{ - char *str=coord_to_str(c); - fprintf(out,"%s",str); - g_free(str); -} - - -static void -item_bin_dump(struct item_bin *ib, FILE *out) -{ - struct coord *c; - struct attr_bin *a; - struct attr attr; - int *attr_start; - int *attr_end; - int i; - char *str; - - c=(struct coord *)(ib+1); - if (ib->type < type_line) { - dump_coord(c,out); - fprintf(out, " "); - } - attr_start=(int *)(ib+1)+ib->clen; - attr_end=(int *)ib+ib->len+1; - fprintf(out,"type=%s", item_to_name(ib->type)); - while (attr_start < attr_end) { - a=(struct attr_bin *)(attr_start); - attr_start+=a->len+1; - attr.type=a->type; - attr_data_set(&attr, (a+1)); - str=attr_to_text(&attr, NULL, 1); - fprintf(out," %s=\"%s\"", attr_to_name(a->type), str); - g_free(str); - } - fprintf(out," debug=\"length=%d\"", ib->len); - fprintf(out,"\n"); - if (ib->type >= type_line) { - for (i = 0 ; i < ib->clen/2 ; i++) { - dump_coord(c+i,out); - fprintf(out,"\n"); - } - } -} - -static int -item_bin_read(struct item_bin *ib, FILE *in) -{ - if (fread(ib, 4, 1, in) == 0) - return 0; - if (!ib->len) - return 1; - if (fread((unsigned char *)ib+4, ib->len*4, 1, in)) - return 2; - return 0; -} - -static int -xml_get_attribute(char *xml, char *attribute, char *buffer, int buffer_size) -{ - int len=strlen(attribute); - char *pos,*i,s,attr[len+2]; - strcpy(attr, attribute); - strcpy(attr+len, "="); - pos=strstr(xml, attr); - if (! pos) - return 0; - pos+=len+1; - s=*pos++; - if (! s) - return 0; - i=strchr(pos, s); - if (! i) - return 0; - if (i - pos > buffer_size) { - fprintf(stderr,"Buffer overflow %ld vs %d\n", (long)(i-pos), buffer_size); - return 0; - } - strncpy(buffer, pos, i-pos); - buffer[i-pos]='\0'; - return 1; -} - -static int node_is_tagged; -static void relation_add_tag(char *k, char *v); - -static int -access_value(char *v) -{ - if (!strcmp(v,"1")) - return 1; - if (!strcmp(v,"yes")) - return 1; - if (!strcmp(v,"designated")) - return 1; - if (!strcmp(v,"permissive")) - return 1; - if (!strcmp(v,"0")) - return 2; - if (!strcmp(v,"no")) - return 2; - if (!strcmp(v,"agricultural")) - return 2; - if (!strcmp(v,"forestry")) - return 2; - if (!strcmp(v,"private")) - return 2; - if (!strcmp(v,"delivery")) - return 2; - if (!strcmp(v,"destination")) - return 2; - return 3; -} - -static void -add_tag(char *k, char *v) -{ - int idx,level=2; - char buffer[BUFFER_SIZE*2+2]; - if (! strcmp(k,"ele")) - level=9; - if (! strcmp(k,"time")) - level=9; - if (! strcmp(k,"created_by")) - level=9; - if (! strncmp(k,"tiger:",6) || !strcmp(k,"AND_nodes")) - level=9; - if (! strcmp(k,"converted_by") || ! strcmp(k,"source")) - level=8; - if (! strncmp(k,"osmarender:",11) || !strncmp(k,"svg:",4)) - level=8; - if (! strcmp(k,"layer")) - level=7; - if (! strcasecmp(v,"true") || ! strcasecmp(v,"yes")) - v="1"; - if (! strcasecmp(v,"false") || ! strcasecmp(v,"no")) - v="0"; - if (! strcmp(k,"oneway")) { - if (!strcmp(v,"1")) { - flags[0] |= AF_ONEWAY | AF_ROUNDABOUT_VALID; - } - if (! strcmp(v,"-1")) { - flags[0] |= AF_ONEWAYREV | AF_ROUNDABOUT_VALID; - } - if (!in_way) - level=6; - else - level=5; - } - if (! strcmp(k,"junction")) { - if (! strcmp(v,"roundabout")) - flags[0] |= AF_ONEWAY | AF_ROUNDABOUT | AF_ROUNDABOUT_VALID; - } - if (! strcmp(k,"maxspeed")) { - if (strstr(v, "mph")) { - maxspeed_attr_value = (int)floor(atof(v) * 1.609344); - } else { - maxspeed_attr_value = atoi(v); - } - if (maxspeed_attr_value) - flags[0] |= AF_SPEED_LIMIT; - level=5; - } - if (! strcmp(k,"access")) { - flags[access_value(v)] |= AF_DANGEROUS_GOODS|AF_EMERGENCY_VEHICLES|AF_TRANSPORT_TRUCK|AF_DELIVERY_TRUCK|AF_PUBLIC_BUS|AF_TAXI|AF_HIGH_OCCUPANCY_CAR|AF_CAR|AF_MOTORCYCLE|AF_MOPED|AF_HORSE|AF_BIKE|AF_PEDESTRIAN; - level=5; - } - if (! strcmp(k,"vehicle")) { - flags[access_value(v)] |= AF_DANGEROUS_GOODS|AF_EMERGENCY_VEHICLES|AF_TRANSPORT_TRUCK|AF_DELIVERY_TRUCK|AF_PUBLIC_BUS|AF_TAXI|AF_HIGH_OCCUPANCY_CAR|AF_CAR|AF_MOTORCYCLE|AF_MOPED|AF_BIKE; - level=5; - } - if (! strcmp(k,"motorvehicle")) { - flags[access_value(v)] |= AF_DANGEROUS_GOODS|AF_EMERGENCY_VEHICLES|AF_TRANSPORT_TRUCK|AF_DELIVERY_TRUCK|AF_PUBLIC_BUS|AF_TAXI|AF_HIGH_OCCUPANCY_CAR|AF_CAR|AF_MOTORCYCLE|AF_MOPED; - level=5; - } - if (! strcmp(k,"bicycle")) { - flags[access_value(v)] |= AF_BIKE; - level=5; - } - if (! strcmp(k,"foot")) { - flags[access_value(v)] |= AF_PEDESTRIAN; - level=5; - } - if (! strcmp(k,"horse")) { - flags[access_value(v)] |= AF_HORSE; - level=5; - } - if (! strcmp(k,"moped")) { - flags[access_value(v)] |= AF_MOPED; - level=5; - } - if (! strcmp(k,"motorcycle")) { - flags[access_value(v)] |= AF_MOTORCYCLE; - level=5; - } - if (! strcmp(k,"motorcar")) { - flags[access_value(v)] |= AF_CAR; - level=5; - } - if (! strcmp(k,"hov")) { - flags[access_value(v)] |= AF_HIGH_OCCUPANCY_CAR; - level=5; - } - if (! strcmp(k,"bus")) { - flags[access_value(v)] |= AF_PUBLIC_BUS; - level=5; - } - if (! strcmp(k,"taxi")) { - flags[access_value(v)] |= AF_TAXI; - level=5; - } - if (! strcmp(k,"goods")) { - flags[access_value(v)] |= AF_DELIVERY_TRUCK; - level=5; - } - if (! strcmp(k,"hgv")) { - flags[access_value(v)] |= AF_TRANSPORT_TRUCK; - level=5; - } - if (! strcmp(k,"emergency")) { - flags[access_value(v)] |= AF_EMERGENCY_VEHICLES; - level=5; - } - if (! strcmp(k,"hazmat")) { - flags[access_value(v)] |= AF_DANGEROUS_GOODS; - level=5; - } - if (! strcmp(k,"note")) - level=5; - if (! strcmp(k,"name")) { - attr_strings_save(attr_string_label, v); - level=5; - } - if (! strcmp(k,"addr:email")) { - attr_strings_save(attr_string_email, v); - level=5; - } - if (! strcmp(k,"addr:housenumber")) { - attr_strings_save(attr_string_house_number, v); - level=5; - } - if (! strcmp(k,"addr:street")) { - attr_strings_save(attr_string_street_name, v); - level=5; - } - if (! strcmp(k,"phone")) { - attr_strings_save(attr_string_phone, v); - level=5; - } - if (! strcmp(k,"fax")) { - attr_strings_save(attr_string_fax, v); - level=5; - } - if (! strcmp(k,"postal")) { - attr_strings_save(attr_string_postal, v); - level=5; - } - if (! strcmp(k,"openGeoDB:postal_codes") && !attr_strings[attr_string_postal]) { - attr_strings_save(attr_string_postal, v); - level=5; - } - if (! strcmp(k,"population")) { - attr_strings_save(attr_string_population, v); - level=5; - } - if (! strcmp(k,"openGeoDB:population") && !attr_strings[attr_string_population]) { - attr_strings_save(attr_string_population, v); - level=5; - } - if (! strcmp(k,"ref")) { - if (in_way) - attr_strings_save(attr_string_street_name_systematic, v); - level=5; - } - if (! strcmp(k,"is_in")) { - strcpy(is_in_buffer, v); - level=5; - } - if (! strcmp(k,"gnis:ST_alpha")) { - /* assume a gnis tag means it is part of the USA: - http://en.wikipedia.org/wiki/Geographic_Names_Information_System - many US towns do not have is_in tags - */ - strcpy(is_in_buffer, "USA"); - level=5; - } - if (! strcmp(k,"lanes")) { - level=5; - } - if (attr_debug_level >= level) { - int bytes_left = sizeof( debug_attr_buffer ) - strlen(debug_attr_buffer) - 1; - if ( bytes_left > 0 ) - { - snprintf(debug_attr_buffer+strlen(debug_attr_buffer), bytes_left, " %s=%s", k, v); - debug_attr_buffer[ sizeof( debug_attr_buffer ) - 1 ] = '\0'; - node_is_tagged=1; - } - } - if (level < 6) - node_is_tagged=1; - - strcpy(buffer,"*=*"); - if ((idx=(int)(long)g_hash_table_lookup(attr_hash, buffer))) - attr_present[idx]=1; - - sprintf(buffer,"%s=*", k); - if ((idx=(int)(long)g_hash_table_lookup(attr_hash, buffer))) - attr_present[idx]=2; - - sprintf(buffer,"*=%s", v); - if ((idx=(int)(long)g_hash_table_lookup(attr_hash, buffer))) - attr_present[idx]=2; - - sprintf(buffer,"%s=%s", k, v); - if ((idx=(int)(long)g_hash_table_lookup(attr_hash, buffer))) - attr_present[idx]=4; -} - -struct entity { - char *entity; - char c; -} entities[]= { - {""",'"'}, - {"'",'\''}, - {"&",'&'}, - {"<",'<'}, - {">",'>'}, -}; - -static void -decode_entities(char *buffer) -{ - char *pos=buffer; - int i,len,found; - - while ((pos=strchr(pos, '&'))) { - found=0; - for (i = 0 ; i < sizeof(entities)/sizeof(struct entity); i++) { - len=strlen(entities[i].entity); - if (!strncmp(pos, entities[i].entity, len)) { - *pos=entities[i].c; - memmove(pos+1, pos+len, strlen(pos+len)+1); - found=1; - break; - } - } - pos++; - } -} - -static int -parse_tag(char *p) -{ - char k_buffer[BUFFER_SIZE]; - char v_buffer[BUFFER_SIZE]; - if (!xml_get_attribute(p, "k", k_buffer, BUFFER_SIZE)) - return 0; - if (!xml_get_attribute(p, "v", v_buffer, BUFFER_SIZE)) - return 0; - decode_entities(v_buffer); - if (in_relation) - relation_add_tag(k_buffer, v_buffer); - else - add_tag(k_buffer, v_buffer); - return 1; -} - - -struct buffer { - int malloced_step; - long long malloced; - unsigned char *base; - long long size; -}; - -static void save_buffer(char *filename, struct buffer *b, long long offset); - -static struct tile_head { - int num_subtiles; - int total_size; - char *name; - char *zip_data; - int total_size_used; - int zipnum; - int process; - struct tile_head *next; - // char subtiles[0]; -} *tile_head_root; - - -int coord_count; - -struct node_item { - int id; - char ref_node; - char ref_way; - char ref_ref; - char dummy; - struct coord c; -}; - -static struct buffer node_buffer = { - 64*1024*1024, -}; - - -static char** th_get_subtile( const struct tile_head* th, int idx ) -{ - char* subtile_ptr = NULL; - subtile_ptr = (char*)th + sizeof( struct tile_head ) + idx * sizeof( char *); - return (char**)subtile_ptr; -} - -static void -extend_buffer(struct buffer *b) -{ - b->malloced+=b->malloced_step; - b->base=realloc(b->base, b->malloced); - if (b->base == NULL) { - fprintf(stderr,"realloc of %d bytes failed\n",(int)b->malloced); - exit(1); - } - -} - -int nodeid_last; -GHashTable *node_hash,*way_hash; - -static void -node_buffer_to_hash(void) -{ - int i,count=node_buffer.size/sizeof(struct node_item); - struct node_item *ni=(struct node_item *)node_buffer.base; - for (i = 0 ; i < count ; i++) - g_hash_table_insert(node_hash, (gpointer)(long)(ni[i].id), (gpointer)(long)i); -} - -static struct node_item *ni; - -static void -flush_nodes(int final) -{ - fprintf(stderr,"flush_nodes %d\n",final); - save_buffer("coords.tmp",&node_buffer,slices*slice_size); - if (!final) { - node_buffer.size=0; - } - slices++; -} - -static void -add_node(int id, double lat, double lon) -{ - if (node_buffer.size + sizeof(struct node_item) > node_buffer.malloced) - extend_buffer(&node_buffer); - attr_strings_clear(); - node_is_tagged=0; - nodeid=id; - item.type=type_point_unkn; - debug_attr_buffer[0]='\0'; - is_in_buffer[0]='\0'; - debug_attr_buffer[0]='\0'; - osmid_attr.type=attr_osm_nodeid; - osmid_attr.len=3; - osmid_attr_value=id; - if (node_buffer.size + sizeof(struct node_item) > slice_size) { - flush_nodes(0); - } - ni=(struct node_item *)(node_buffer.base+node_buffer.size); - ni->id=id; - ni->ref_node=0; - ni->ref_way=0; - ni->ref_ref=0; - ni->dummy=0; - ni->c.x=lon*6371000.0*M_PI/180; - ni->c.y=log(tan(M_PI_4+lat*M_PI/360))*6371000.0; - node_buffer.size+=sizeof(struct node_item); - if (! node_hash) { - if (ni->id > nodeid_last) { - nodeid_last=ni->id; - } else { - fprintf(stderr,"INFO: Nodes out of sequence (new %d vs old %d), adding hash\n", ni->id, nodeid_last); - node_hash=g_hash_table_new(NULL, NULL); - node_buffer_to_hash(); - } - } else - if (!g_hash_table_lookup(node_hash, (gpointer)(long)(ni->id))) - g_hash_table_insert(node_hash, (gpointer)(long)(ni->id), (gpointer)(long)(ni-(struct node_item *)node_buffer.base)); - else { - node_buffer.size-=sizeof(struct node_item); - nodeid=0; - } - -} - -static int -parse_node(char *p) -{ - char id_buffer[BUFFER_SIZE]; - char lat_buffer[BUFFER_SIZE]; - char lon_buffer[BUFFER_SIZE]; - if (!xml_get_attribute(p, "id", id_buffer, BUFFER_SIZE)) - return 0; - if (!xml_get_attribute(p, "lat", lat_buffer, BUFFER_SIZE)) - return 0; - if (!xml_get_attribute(p, "lon", lon_buffer, BUFFER_SIZE)) - return 0; - add_node(atoi(id_buffer), atof(lat_buffer), atof(lon_buffer)); - return 1; -} - - -static struct node_item * -node_item_get(int id) -{ - struct node_item *ni=(struct node_item *)(node_buffer.base); - int count=node_buffer.size/sizeof(struct node_item); - int interval=count/4; - int p=count/2; - if(interval==0) { - // If fewer than 4 nodes defined so far set interval to 1 to - // avoid infinite loop - interval = 1; - } - if (node_hash) { - int i; - i=(int)(long)(g_hash_table_lookup(node_hash, (gpointer)(long)id)); - return ni+i; - } - if (ni[0].id > id) - return NULL; - if (ni[count-1].id < id) - return NULL; - while (ni[p].id != id) { -#if 0 - fprintf(stderr,"p=%d count=%d interval=%d id=%d ni[p].id=%d\n", p, count, interval, id, ni[p].id); -#endif - if (ni[p].id < id) { - p+=interval; - if (interval == 1) { - if (p >= count) - return NULL; - if (ni[p].id > id) - return NULL; - } else { - if (p >= count) - p=count-1; - } - } else { - p-=interval; - if (interval == 1) { - if (p < 0) - return NULL; - if (ni[p].id < id) - return NULL; - } else { - if (p < 0) - p=0; - } - } - if (interval > 1) - interval/=2; - } - - return &ni[p]; -} - -static int -load_node(FILE *coords, int p, struct node_item *ret) -{ - fseek(coords, p*sizeof(struct node_item), SEEK_SET); - if (fread(ret, sizeof(*ret), 1, coords) != 1) { - fprintf(stderr,"read failed\n"); - return 0; - } - return 1; -} - -static int -node_item_get_from_file(FILE *coords, int id, struct node_item *ret) -{ - int count; - int interval; - int p; - if (node_hash) { - int i; - i=(int)(long)(g_hash_table_lookup(node_hash, (gpointer)(long)id)); - fseek(coords, i*sizeof(*ret), SEEK_SET); - if (fread(ret, sizeof(*ret), 1, coords) == 1) - return 1; - else - return 0; - } - - fseek(coords, 0, SEEK_END); - count=ftell(coords)/sizeof(struct node_item); - interval=count/4; - p=count/2; - if(interval==0) { - // If fewer than 4 nodes defined so far set interval to 1 to - // avoid infinite loop - interval = 1; - } - if (!load_node(coords, p, ret)) - return 0; - for (;;) { - if (ret->id == id) - return 1; - if (ret->id < id) { - p+=interval; - if (interval == 1) { - if (p >= count) - return 0; - if (!load_node(coords, p, ret)) - return 0; - if (ret->id > id) - return 0; - } else { - if (p >= count) - p=count-1; - if (!load_node(coords, p, ret)) - return 0; - } - } else { - p-=interval; - if (interval == 1) { - if (p < 0) - return 0; - if (!load_node(coords, p, ret)) - return 0; - if (ret->id < id) - return 0; - } else { - if (p < 0) - p=0; - if (!load_node(coords, p, ret)) - return 0; - } - } - if (interval > 1) - interval/=2; - } -} - -static void -add_way(int id) -{ - static int wayid_last; - wayid=id; - coord_count=0; - attr_strings_clear(); - item.type=type_street_unkn; - debug_attr_buffer[0]='\0'; - maxspeed_attr_value=0; - flags_attr_value = 0; - memset(flags, 0, sizeof(flags)); - debug_attr_buffer[0]='\0'; - osmid_attr_value=id; - if (wayid < wayid_last && !way_hash) { - fprintf(stderr,"INFO: Ways out of sequence (new %d vs old %d), adding hash\n", wayid, wayid_last); - way_hash=g_hash_table_new(NULL, NULL); - } - wayid_last=wayid; -} - -static int -parse_way(char *p) -{ - char id_buffer[BUFFER_SIZE]; - if (!xml_get_attribute(p, "id", id_buffer, BUFFER_SIZE)) - return 0; - add_way(atoi(id_buffer)); - return 1; -} - -static int -add_id_attr(char *p, enum attr_type attr_type) -{ - struct attr idattr = { attr_type }; - char id_buffer[BUFFER_SIZE]; - if (!xml_get_attribute(p, "id", id_buffer, BUFFER_SIZE)) - return 0; - current_id=atoll(id_buffer); - idattr.u.num64=¤t_id; - item_bin_add_attr(item_bin, &idattr); - return 1; -} - -char relation_type[BUFFER_SIZE]; -char iso_code[BUFFER_SIZE]; -int admin_level; -int boundary; - - -static int -parse_relation(char *p) -{ - debug_attr_buffer[0]='\0'; - relation_type[0]='\0'; - iso_code[0]='\0'; - admin_level=-1; - boundary=0; - item_bin_init(item_bin, type_none); - if (!add_id_attr(p, attr_osm_relationid)) - return 0; - return 1; -} - -static void -end_relation(FILE *turn_restrictions) -{ - struct item_bin *ib=(struct item_bin *)buffer; -#if 0 - if (!strcmp(relation_type, "multipolygon") && boundary && admin_level != -1) { - if (admin_level == 2) { - FILE *f; - fprintf(stderr,"Multipolygon for %s\n", iso_code); - char *name=g_strdup_printf("country_%s.tmp",iso_code); - f=fopen(name,"w"); - item_bin_write(item_bin, f); - fclose(f); - } - } -#endif - if (!strcmp(relation_type, "restriction") && (ib->type == type_street_turn_restriction_no || ib->type == type_street_turn_restriction_only)) - item_bin_write(item_bin, turn_restrictions); -} - -static int -parse_member(char *p) -{ - char type_buffer[BUFFER_SIZE]; - char ref_buffer[BUFFER_SIZE]; - char role_buffer[BUFFER_SIZE]; - char member_buffer[BUFFER_SIZE*3+3]; - int type; - struct attr memberattr = { attr_osm_member }; - if (!xml_get_attribute(p, "type", type_buffer, BUFFER_SIZE)) - return 0; - if (!xml_get_attribute(p, "ref", ref_buffer, BUFFER_SIZE)) - return 0; - if (!xml_get_attribute(p, "role", role_buffer, BUFFER_SIZE)) - return 0; - if (!strcmp(type_buffer,"node")) - type=1; - else if (!strcmp(type_buffer,"way")) - type=2; - else if (!strcmp(type_buffer,"relation")) - type=3; - else { - fprintf(stderr,"Unknown type %s\n",type_buffer); - type=0; - } - sprintf(member_buffer,"%d:%s:%s", type, ref_buffer, role_buffer); - memberattr.u.str=member_buffer; - item_bin_add_attr(item_bin, &memberattr); - - return 1; -} - - -static void -relation_add_tag(char *k, char *v) -{ -#if 0 - fprintf(stderr,"add tag %s %s\n",k,v); -#endif - if (!strcmp(k,"type")) - strcpy(relation_type, v); - else if (!strcmp(k,"restriction")) { - if (!strncmp(v,"no_",3)) { - item_bin->type=type_street_turn_restriction_no; - } else if (!strncmp(v,"only_",5)) { - item_bin->type=type_street_turn_restriction_only; - } else { - item_bin->type=type_none; - osm_warning("relation", current_id, 0, "Unknown restriction %s\n",v); - } - } else if (!strcmp(k,"admin_level")) { - admin_level=atoi(v); - } else if (!strcmp(k,"boundary")) { - if (!strcmp(v,"administrative")) { - boundary=1; - } - } else if (!strcmp(k,"ISO3166-1")) { - strcpy(iso_code, v); - } -} - - -static int -attr_longest_match(struct attr_mapping **mapping, int mapping_count, enum item_type *types, int types_count) -{ - int i,j,longest=0,ret=0,sum,val; - struct attr_mapping *curr; - for (i = 0 ; i < mapping_count ; i++) { - sum=0; - curr=mapping[i]; - for (j = 0 ; j < curr->attr_present_idx_count ; j++) { - val=attr_present[curr->attr_present_idx[j]]; - if (val) - sum+=val; - else { - sum=-1; - break; - } - } - if (sum > longest) { - longest=sum; - ret=0; - } - if (sum > 0 && sum == longest && ret < types_count) - types[ret++]=curr->type; - } - memset(attr_present, 0, sizeof(*attr_present)*attr_present_count); - return ret; -} - -static void -end_way(FILE *out) -{ - int i,count; - int *def_flags,add_flags; - enum item_type types[10]; - - if (! out) - return; - if (dedupe_ways_hash) { - if (g_hash_table_lookup(dedupe_ways_hash, (gpointer)(long)wayid)) - return; - g_hash_table_insert(dedupe_ways_hash, (gpointer)(long)wayid, (gpointer)1); - } - count=attr_longest_match(attr_mapping_way, attr_mapping_way_count, types, sizeof(types)/sizeof(enum item_type)); - if (!count) { - count=1; - types[0]=type_street_unkn; - } - if (count >= 10) { - fprintf(stderr,"way id %ld\n",osmid_attr_value); - assert(count < 10); - } - for (i = 0 ; i < count ; i++) { - add_flags=0; - if (types[i] == type_none) - continue; - item_bin_init(item_bin,types[i]); - item_bin_add_coord(item_bin, coord_buffer, coord_count); - def_flags=item_get_default_flags(types[i]); - if (def_flags) { - if (coverage) { - item.type=type_coverage; - } else { - flags_attr_value=(*def_flags | flags[0] | flags[1]) & ~flags[2]; - if (flags_attr_value != *def_flags) - add_flags=1; - } - } - item_bin_add_attr_string(item_bin, def_flags ? attr_street_name : attr_label, attr_strings[attr_string_label]); - item_bin_add_attr_string(item_bin, attr_street_name_systematic, attr_strings[attr_string_street_name_systematic]); - item_bin_add_attr_longlong(item_bin, attr_osm_wayid, osmid_attr_value); - if (debug_attr_buffer[0]) - item_bin_add_attr_string(item_bin, attr_debug, debug_attr_buffer); - if (add_flags) - item_bin_add_attr_int(item_bin, attr_flags, flags_attr_value); - if (maxspeed_attr_value) - item_bin_add_attr_int(item_bin, attr_maxspeed, maxspeed_attr_value); - item_bin_write(item_bin,out); - } -} - -struct population_table { - enum item_type type; - int population; -}; - -static struct population_table town_population[] = { - {type_town_label_0e0,0}, - {type_town_label_1e0,1}, - {type_town_label_2e0,2}, - {type_town_label_5e0,5}, - {type_town_label_1e1,10}, - {type_town_label_2e1,20}, - {type_town_label_5e1,50}, - {type_town_label_1e2,100}, - {type_town_label_2e2,200}, - {type_town_label_5e2,500}, - {type_town_label_1e3,1000}, - {type_town_label_2e3,2000}, - {type_town_label_5e3,5000}, - {type_town_label_1e4,10000}, - {type_town_label_2e4,20000}, - {type_town_label_5e4,50000}, - {type_town_label_1e5,100000}, - {type_town_label_2e5,200000}, - {type_town_label_5e5,500000}, - {type_town_label_1e6,1000000}, - {type_town_label_2e6,2000000}, - {type_town_label_5e6,5000000}, - {type_town_label_1e7,1000000}, -}; - -static struct population_table district_population[] = { - {type_district_label_0e0,0}, - {type_district_label_1e0,1}, - {type_district_label_2e0,2}, - {type_district_label_5e0,5}, - {type_district_label_1e1,10}, - {type_district_label_2e1,20}, - {type_district_label_5e1,50}, - {type_district_label_1e2,100}, - {type_district_label_2e2,200}, - {type_district_label_5e2,500}, - {type_district_label_1e3,1000}, - {type_district_label_2e3,2000}, - {type_district_label_5e3,5000}, - {type_district_label_1e4,10000}, - {type_district_label_2e4,20000}, - {type_district_label_5e4,50000}, - {type_district_label_1e5,100000}, - {type_district_label_2e5,200000}, - {type_district_label_5e5,500000}, - {type_district_label_1e6,1000000}, - {type_district_label_2e6,2000000}, - {type_district_label_5e6,5000000}, - {type_district_label_1e7,1000000}, -}; - -static void -end_node(FILE *out) -{ - int conflict,count,i; - char *postal; - enum item_type types[10]; - struct country_table *result=NULL, *lookup; - if (!out || ! node_is_tagged || ! nodeid) - return; - count=attr_longest_match(attr_mapping_node, attr_mapping_node_count, types, sizeof(types)/sizeof(enum item_type)); - if (!count) { - types[0]=type_point_unkn; - count=1; - } - assert(count < 10); - for (i = 0 ; i < count ; i++) { - conflict=0; - if (types[i] == type_none) - continue; - item_bin_init(item_bin, types[i]); - if (item_is_town(*item_bin) && attr_strings[attr_string_population]) { - int i,count,population=atoi(attr_strings[attr_string_population]); - struct population_table *table; - if (population < 0) - population=0; - if (item_is_district(*item_bin)) { - table=district_population; - count=sizeof(district_population)/sizeof(district_population[0]); - } else { - table=town_population; - count=sizeof(town_population)/sizeof(town_population[0]); - } - for (i = 0 ; i < count ; i++) { - if (population < table[i].population) - break; - } - item_bin_set_type(item_bin, table[i-1].type); - } - item_bin_add_coord(item_bin, &ni->c, 1); - item_bin_add_attr_string(item_bin, item_is_town(*item_bin) ? attr_town_name : attr_label, attr_strings[attr_string_label]); - item_bin_add_attr_string(item_bin, attr_house_number, attr_strings[attr_string_house_number]); - item_bin_add_attr_string(item_bin, attr_street_name, attr_strings[attr_string_street_name]); - item_bin_add_attr_string(item_bin, attr_phone, attr_strings[attr_string_phone]); - item_bin_add_attr_string(item_bin, attr_fax, attr_strings[attr_string_fax]); - item_bin_add_attr_string(item_bin, attr_email, attr_strings[attr_string_email]); - item_bin_add_attr_string(item_bin, attr_url, attr_strings[attr_string_url]); - item_bin_add_attr_longlong(item_bin, attr_osm_nodeid, osmid_attr_value); - item_bin_add_attr_string(item_bin, attr_debug, debug_attr_buffer); - postal=attr_strings[attr_string_postal]; - if (postal) { - char *sep=strchr(postal,','); - if (sep) - *sep='\0'; - item_bin_add_attr_string(item_bin, item_is_town(*item_bin) ? attr_town_postal : attr_postal, postal); - } - item_bin_write(item_bin,out); - if (item_is_town(*item_bin) && attr_strings[attr_string_label]) { - char *tok,*buf=is_in_buffer; - if (!buf[0]) - strcpy(is_in_buffer, "Unknown"); - while ((tok=strtok(buf, ","))) { - while (*tok==' ') - tok++; - lookup=g_hash_table_lookup(country_table_hash,tok); - if (lookup) { - if (result && result->countryid != lookup->countryid) { - osm_warning("node",nodeid,0,"conflict for %s %s country %d vs %d\n", attr_strings[attr_string_label], debug_attr_buffer, lookup->countryid, result->countryid); - conflict=1; - } else - result=lookup; - } - buf=NULL; - } - if (result && !conflict) { - if (!result->file) { - char *name=g_strdup_printf("country_%d.bin.unsorted", result->countryid); - result->file=fopen(name,"wb"); - g_free(name); - } - if (result->file) { - int i,words=0; - char *town_name=attr_strings[attr_string_label]; - char *word=town_name; - do { - for (i = 0 ; i < 3 ; i++) { - char *str=linguistics_expand_special(word, i); - if (str) { - item_bin_init(item_bin, item_bin->type); - item_bin_add_coord(item_bin, &ni->c, 1); - if (i || words) - item_bin_add_attr_string(item_bin, attr_town_name_match, str); - item_bin_add_attr_string(item_bin, attr_town_name, town_name); - item_bin_add_attr_string(item_bin, attr_town_postal, postal); - item_bin_write(item_bin, result->file); - g_free(str); - } - } - word=linguistics_next_word(word); - words++; - } while (word); - } - - } - } - } - processed_nodes_out++; -} - -static int -sort_countries_compare(const void *p1, const void *p2) -{ - struct item_bin *ib1=*((struct item_bin **)p1),*ib2=*((struct item_bin **)p2); - struct attr_bin *attr1,*attr2; - char *s1,*s2; - assert(ib1->clen==2); - assert(ib2->clen==2); - attr1=(struct attr_bin *)((int *)(ib1+1)+ib1->clen); - attr2=(struct attr_bin *)((int *)(ib2+1)+ib1->clen); - assert(attr1->type == attr_town_name || attr1->type == attr_town_name_match); - assert(attr2->type == attr_town_name || attr2->type == attr_town_name_match); - s1=(char *)(attr1+1); - s2=(char *)(attr2+1); - return strcmp(s1, s2); -#if 0 - fprintf(stderr,"sort_countries_compare p1=%p p2=%p %s %s\n",p1,p2,s1,s2); -#endif - return 0; -} - -static void -sort_countries(int keep_tmpfiles) -{ - int i,j,count; - struct country_table *co; - struct coord *c; - struct item_bin *ib; - FILE *f; - char *name; - unsigned char *p,**idx,*buffer; - for (i = 0 ; i < sizeof(country_table)/sizeof(struct country_table) ; i++) { - co=&country_table[i]; - if (co->file) { - fclose(co->file); - co->file=NULL; - } - name=g_strdup_printf("country_%d.bin.unsorted", co->countryid); - if (file_get_contents(name, &buffer, &co->size)) { - if(!keep_tmpfiles) - unlink(name); - g_free(name); - ib=(struct item_bin *)buffer; - p=buffer; - count=0; - while (p < buffer+co->size) { - count++; - p+=(*((int *)p)+1)*4; - } - idx=malloc(count*sizeof(void *)); - assert(idx != NULL); - p=buffer; - for (j = 0 ; j < count ; j++) { - idx[j]=p; - p+=(*((int *)p)+1)*4; - } - qsort(idx, count, sizeof(void *), sort_countries_compare); - name=g_strdup_printf("country_%d.bin", co->countryid); - f=fopen(name,"wb"); - for (j = 0 ; j < count ; j++) { - ib=(struct item_bin *)(idx[j]); - c=(struct coord *)(ib+1); - fwrite(ib, (ib->len+1)*4, 1, f); - if (j) - bbox_extend(c, &co->r); - else { - co->r.l=*c; - co->r.h=*c; - } - } - fclose(f); - } - g_free(name); - } -} - -struct relation_member { - int type; - long long id; - char *role; -}; - -static int -get_relation_member(char *str, struct relation_member *memb) -{ - int len; - sscanf(str,"%d:%Ld:%n",&memb->type,&memb->id,&len); - memb->role=str+len; - return 1; -} - -static int -search_relation_member(struct item_bin *ib, char *role, struct relation_member *memb, int *min_count) -{ - char *str=NULL; - int count=0; - while ((str=item_bin_get_attr(ib, attr_osm_member, str))) { - if (!get_relation_member(str, memb)) - return 0; - count++; - if (!strcmp(memb->role, role) && (!min_count || *min_count < count)) { - if (min_count) - *min_count=count; - return 1; - } - } - return 0; -} - -static int -load_way_index(FILE *ways_index, int p, long long *idx) -{ - int step=sizeof(*idx)*2; - fseek(ways_index, p*step, SEEK_SET); - if (fread(idx, step, 1, ways_index) != 1) { - fprintf(stderr,"read failed\n"); - return 0; - } - return 1; -} - - -static int -seek_to_way(FILE *way, FILE *ways_index, long long wayid) -{ - long offset; - long long idx[2]; - int count,interval,p; - if (way_hash) { - if (!(g_hash_table_lookup_extended(way_hash, (gpointer)(long)wayid, NULL, (gpointer)&offset))) - return 0; - fseek(way, offset, SEEK_SET); - return 1; - } - fseek(ways_index, 0, SEEK_END); - count=ftell(ways_index)/sizeof(idx); - interval=count/4; - p=count/2; - if(interval==0) { - // If fewer than 4 nodes defined so far set interval to 1 to - // avoid infinite loop - interval = 1; - } - if (!load_way_index(ways_index, p, idx)) - return 0; - for (;;) { - if (idx[0] == wayid) { - fseek(way, idx[1], SEEK_SET); - return 1; - } - if (idx[0] < wayid) { - p+=interval; - if (interval == 1) { - if (p >= count) - return 0; - if (!load_way_index(ways_index, p, idx)) - return 0; - if (idx[0] > wayid) - return 0; - } else { - if (p >= count) - p=count-1; - if (!load_way_index(ways_index, p, idx)) - return 0; - } - } else { - p-=interval; - if (interval == 1) { - if (p < 0) - return 0; - if (!load_way_index(ways_index, p, idx)) - return 0; - if (idx[0] < wayid) - return 0; - } else { - if (p < 0) - p=0; - if (!load_way_index(ways_index, p, idx)) - return 0; - } - } - if (interval > 1) - interval/=2; - } -} - - -static struct coord * -get_way(FILE *way, FILE *ways_index, struct coord *c, long long wayid, struct item_bin *ret, int debug) -{ - long long currid; - int last; - struct coord *ic; - if (!seek_to_way(way, ways_index, wayid)) { - if (debug) - fprintf(stderr,"not found in index"); - return NULL; - } - while (item_bin_read(ret, way)) { - currid=item_bin_get_wayid(ret); - if (debug) - fprintf(stderr,"%Ld:",currid); - if (currid != wayid) - return NULL; - ic=(struct coord *)(ret+1); - last=ret->clen/2-1; - if (debug) - fprintf(stderr,"(0x%x,0x%x)-(0x%x,0x%x)",ic[0].x,ic[0].y,ic[last].x,ic[last].y); - if (!c) - return &ic[0]; - if (ic[0].x == c->x && ic[0].y == c->y) - return &ic[last]; - if (ic[last].x == c->x && ic[last].y == c->y) - return &ic[0]; - } - return NULL; -} - -static void -process_turn_restrictions(FILE *in, FILE *coords, FILE *ways, FILE *ways_index, FILE *out) -{ - struct relation_member fromm,tom,viam,tmpm; - struct node_item ni; - long long relid; - char from_buffer[65536],to_buffer[65536],via_buffer[65536]; - struct item_bin *ib=(struct item_bin *)buffer,*from=(struct item_bin *)from_buffer,*to=(struct item_bin *)to_buffer,*via=(struct item_bin *)via_buffer; - struct coord *fromc,*toc,*viafrom,*viato,*tmp; - fseek(in, 0, SEEK_SET); - int min_count; - while (item_bin_read(ib, in)) { - relid=item_bin_get_relationid(ib); - min_count=0; - if (!search_relation_member(ib, "from",&fromm,&min_count)) { - osm_warning("relation",relid,0,"turn restriction: from member missing\n"); - continue; - } - if (search_relation_member(ib, "from",&tmpm,&min_count)) { - osm_warning("relation",relid,0,"turn restriction: multiple from members\n"); - continue; - } - min_count=0; - if (!search_relation_member(ib, "to",&tom,&min_count)) { - osm_warning("relation",relid,0,"turn restriction: to member missing\n"); - continue; - } - if (search_relation_member(ib, "to",&tmpm,&min_count)) { - osm_warning("relation",relid,0,"turn restriction: multiple to members\n"); - continue; - } - min_count=0; - if (!search_relation_member(ib, "via",&viam,&min_count)) { - osm_warning("relation",relid,0,"turn restriction: via member missing\n"); - continue; - } - if (search_relation_member(ib, "via",&tmpm,&min_count)) { - osm_warning("relation",relid,0,"turn restriction: multiple via member\n"); - continue; - } - if (fromm.type != 2) { - osm_warning("relation",relid,0,"turn restriction: wrong type for from member "); - osm_warning(osm_types[fromm.type],fromm.id,1,"\n"); - continue; - } - if (tom.type != 2) { - osm_warning("relation",relid,0,"turn restriction: wrong type for to member "); - osm_warning(osm_types[tom.type],tom.id,1,"\n"); - continue; - } - if (viam.type != 1 && viam.type != 2) { - osm_warning("relation",relid,0,"turn restriction: wrong type for via member "); - osm_warning(osm_types[viam.type],viam.id,1,"\n"); - continue; - } - if (viam.type == 1) { - if (!node_item_get_from_file(coords, viam.id, &ni)) { - osm_warning("relation",relid,0,"turn restriction: failed to get via member "); - osm_warning(osm_types[viam.type],viam.id,1,"\n"); - continue; - } - viafrom=&ni.c; - viato=&ni.c; - } else { - if (!(viafrom=get_way(ways, ways_index, NULL, viam.id, via, 0))) { - osm_warning("relation",relid,0,"turn restriction: failed to get first via coordinate from "); - osm_warning(osm_types[viam.type],viam.id,1,"\n"); - continue; - } - if (!(viato=get_way(ways, ways_index, viafrom, viam.id, via, 0))) { - osm_warning("relation",relid,0,"turn restriction: failed to get last via coordinate from "); - osm_warning(osm_types[viam.type],viam.id,1,"\n"); - continue; - } - - } -#if 0 - fprintf(stderr,"via %Ld vs %d\n",viam.id, ni.id); - fprintf(stderr,"coord 0x%x,0x%x\n",ni.c.x,ni.c.y); - fprintf(stderr,"Lookup %Ld\n",fromm.id); -#endif - if (!(fromc=get_way(ways, ways_index, viafrom, fromm.id, from, 0))) { - if (viam.type == 1 || !(fromc=get_way(ways, ways_index, viato, fromm.id, from, 0))) { - osm_warning("relation",relid,0,"turn restriction: failed to connect via "); - osm_warning(osm_types[viam.type],viam.id,1," 0x%x,0x%x-0x%x,0x%x to from member ",viafrom->x,viafrom->y,viato->x,viato->y); - osm_warning(osm_types[fromm.type],fromm.id,1," ("); - get_way(ways, ways_index, viafrom, fromm.id, from, 1); - fprintf(stderr,")\n"); - continue; - } else { - tmp=viato; - viato=viafrom; - viafrom=tmp; - } - } - if (!(toc=get_way(ways, ways_index, viato, tom.id, to, 0))) { - osm_warning("relation",relid,0,"turn restriction: failed to connect via "); - osm_warning(osm_types[viam.type],viam.id,1," 0x%x,0x%x-0x%x,0x%x to to member ",viafrom->x,viafrom->y,viato->x,viato->y); - osm_warning(osm_types[tom.type],tom.id,1," ("); - get_way(ways, ways_index, viato, tom.id, to, 1); - fprintf(stderr,")\n"); - continue; - } -#if 0 - fprintf(stderr,"(0x%x,0x%x)-(0x%x,0x%x)-(0x%x,0x%x)\n",fromc->x,fromc->y, ni.c.x, ni.c.y, toc->x, toc->y); -#endif - item_bin_init(ib,ib->type); - item_bin_add_coord(ib, fromc, 1); - item_bin_add_coord(ib, viafrom, 1); - if (viam.type == 2) - item_bin_add_coord(ib, viato, 1); - item_bin_add_coord(ib, toc, 1); - item_bin_write(item_bin, out); - } -} - -enum geom_poly_segment_type { - geom_poly_segment_type_none, - geom_poly_segment_type_way_inner, - geom_poly_segment_type_way_outer, - geom_poly_segment_type_way_left_side, - geom_poly_segment_type_way_right_side, - geom_poly_segment_type_way_unknown, - -}; - -struct geom_poly_segment { - enum geom_poly_segment_type type; - struct coord *first,*last; -}; - -static void -geom_coord_copy(struct coord *from, struct coord *to, int count, int reverse) -{ - int i; - if (!reverse) { - memcpy(to, from, count*sizeof(struct coord)); - return; - } - from+=count; - for (i = 0 ; i < count ; i++) - *to++=*--from; -} - -static void -geom_coord_revert(struct coord *c, int count) -{ - struct coord tmp; - int i; - - for (i = 0 ; i < count/2 ; i++) { - tmp=c[i]; - c[i]=c[count-1-i]; - c[count-1-i]=tmp; - } -} - - -static long long -geom_poly_area(struct coord *c, int count) -{ - long long area=0; - int i,j=0; -#if 0 - fprintf(stderr,"count=%d\n",count); -#endif - for (i=0; itype=second->type; - count=(second->last-second->first)+1; - if (first) - count+=(first->last-first->first); - if (third) - count+=(third->last-third->first); -#if 0 - fprintf(stderr,"count=%d first=%p second=%p third=%p\n",count,first,second,third); - if (first) - fprintf(stderr,"first:0x%x,0x%x-0x%x,0x%x (%d)\n",first->first->x,first->first->y,first->last->x,first->last->y, first->last-first->first+1); - if (second) - fprintf(stderr,"second:0x%x,0x%x-0x%x,0x%x (%d)\n",second->first->x,second->first->y,second->last->x,second->last->y, second->last-second->first+1); - if (third) - fprintf(stderr,"third:0x%x,0x%x-0x%x,0x%x (%d)\n",third->first->x,third->first->y,third->last->x,third->last->y, third->last-third->first+1); -#endif - ret->first=g_new(struct coord, count); - pos=ret->first; - if (first) { - count=(first->last-first->first)+1; - geom_coord_copy(first->first, pos, count, coord_is_equal(*first->first, *second->first)); - pos+=count-1; - } - count=(second->last-second->first)+1; - geom_coord_copy(second->first, pos, count, 0); - pos+=count; - if (third) { - pos--; - count=(third->last-third->first)+1; - geom_coord_copy(third->first, pos, count, coord_is_equal(*third->last, *second->last)); - pos+=count; - } - ret->last=pos-1; -#if 0 - fprintf(stderr,"result:0x%x,0x%x-0x%x,0x%x (%d)\n",ret->first->x,ret->first->y,ret->last->x,ret->last->y, ret->last-ret->first+1); -#endif - list=g_list_prepend(list, ret); -#if 0 - fprintf(stderr,"List=%p\n",list); -#endif - return list; -} - -static void -geom_poly_segment_destroy(struct geom_poly_segment *seg) -{ - g_free(seg->first); - g_free(seg); -} - -static GList * -geom_poly_segments_remove(GList *list, struct geom_poly_segment *seg) -{ - if (seg) { - list=g_list_remove(list, seg); - geom_poly_segment_destroy(seg); - } - return list; -} - -static int -geom_poly_segment_compatible(struct geom_poly_segment *s1, struct geom_poly_segment *s2, int dir) -{ - int same=0,opposite=0; - if (s1->type == geom_poly_segment_type_none || s2->type == geom_poly_segment_type_none) - return 0; - if (s1->type == s2->type) - same=1; - if (s1->type == geom_poly_segment_type_way_inner && s2->type == geom_poly_segment_type_way_outer) - opposite=1; - if (s1->type == geom_poly_segment_type_way_outer && s2->type == geom_poly_segment_type_way_inner) - opposite=1; - if (s1->type == geom_poly_segment_type_way_left_side && s2->type == geom_poly_segment_type_way_right_side) - opposite=1; - if (s1->type == geom_poly_segment_type_way_right_side && s2->type == geom_poly_segment_type_way_left_side) - opposite=1; - if (s1->type == geom_poly_segment_type_way_unknown || s2->type == geom_poly_segment_type_way_unknown) { - same=1; - opposite=1; - } - if (dir < 0) { - if ((opposite && coord_is_equal(*s1->first, *s2->first)) || (same && coord_is_equal(*s1->first, *s2->last))) - return 1; - } else { - if ((opposite && coord_is_equal(*s1->last, *s2->last)) || (same && coord_is_equal(*s1->last, *s2->first))) - return 1; - } - return 0; -} - - -static GList * -geom_poly_segments_sort(GList *in, enum geom_poly_segment_type type) -{ - GList *ret=NULL; - while (in) { - struct geom_poly_segment *seg=in->data; - GList *tmp=ret; - struct geom_poly_segment *merge_first=NULL,*merge_last=NULL; - while (tmp) { - struct geom_poly_segment *cseg=tmp->data; - if (geom_poly_segment_compatible(seg, cseg, -1)) - merge_first=cseg; - if (geom_poly_segment_compatible(seg, cseg, 1)) - merge_last=cseg; - tmp=g_list_next(tmp); - } - if (merge_first == merge_last) - merge_last=NULL; - ret=geom_poly_segments_insert(ret, merge_first, seg, merge_last); - ret=geom_poly_segments_remove(ret, merge_first); - ret=geom_poly_segments_remove(ret, merge_last); - in=g_list_next(in); - } - in=ret; - while (in) { - struct geom_poly_segment *seg=in->data; - if (coord_is_equal(*seg->first, *seg->last)) { - long long area=geom_poly_area(seg->first,seg->last-seg->first+1); - if (type == geom_poly_segment_type_way_right_side && seg->type == geom_poly_segment_type_way_right_side) { - seg->type=area > 0 ? geom_poly_segment_type_way_outer : geom_poly_segment_type_way_inner; - } - } - in=g_list_next(in); - } - return ret; -} - -static struct geom_poly_segment * -item_bin_to_poly_segment(struct item_bin *ib, int type) -{ - struct geom_poly_segment *ret=g_new(struct geom_poly_segment, 1); - int count=ib->clen*sizeof(int)/sizeof(struct coord); - ret->type=type; - ret->first=g_new(struct coord, count); - ret->last=ret->first+count-1; - geom_coord_copy((struct coord *)(ib+1), ret->first, count, 0); - return ret; -} - - -static void -process_countries(FILE *way, FILE *ways_index) -{ - FILE *in=fopen("country_de.tmp","r"); - struct item_bin *ib=(struct item_bin *)buffer; - char buffer2[400000]; - struct item_bin *ib2=(struct item_bin *)buffer2; - GList *segments=NULL,*sort_segments; - fseek(in, 0, SEEK_SET); - while (item_bin_read(ib, in)) { - char *str=NULL; - struct relation_member member; - while ((str=item_bin_get_attr(ib, attr_osm_member, str))) { - if (!get_relation_member(str, &member)) - break; - if (member.type == 2) { - if (!seek_to_way(way, ways_index, member.id)) { - fprintf(stderr,"not found in index"); - break; - } - while (item_bin_read(ib2, way)) { - if (item_bin_get_wayid(ib2) != member.id) - break; - segments=g_list_prepend(segments,item_bin_to_poly_segment(ib2, geom_poly_segment_type_way_unknown)); - break; - } - } - } - } - sort_segments=geom_poly_segments_sort(segments, geom_poly_segment_type_way_left_side); - FILE *tmp=fopen("tst.txt","w"); - while (sort_segments) { - struct geom_poly_segment *seg=sort_segments->data; - if (!seg) { - fprintf(stderr,"is null\n"); - } -#if 0 - int count=seg->last-seg->first+1; - item_bin_init(ib, type_border_country); - item_bin_add_coord(ib, seg->first, count); - item_bin_dump(ib, tmp); -#endif - fprintf(stderr,"segment %p %s area %Ld\n",sort_segments,coord_is_equal(*seg->first, *seg->last) ? "closed":"open",geom_poly_area(seg->first,seg->last-seg->first+1)); - - sort_segments=g_list_next(sort_segments); - } - fclose(tmp); - fclose(in); -} - -static void -node_ref_way(osmid node) -{ - struct node_item *ni; - ni=node_item_get(node); - if (ni) - ni->ref_way++; -} - -static int -resolve_ways(FILE *in, FILE *out) -{ - struct item_bin *ib=(struct item_bin *)buffer; - struct coord *c; - int i; - - fseek(in, 0, SEEK_SET); - for (;;) { - switch (item_bin_read(ib, in)) { - case 0: - return 0; - case 2: - c=(struct coord *)(ib+1); - for (i = 0 ; i < ib->clen/2 ; i++) { - node_ref_way(REF(c[i])); - } - default: - continue; - } - } - - -} - -static void -add_nd(char *p, osmid ref) -{ - SET_REF(coord_buffer[coord_count], ref); - node_ref_way(ref); - coord_count++; - if (coord_count > 65536) { - fprintf(stderr,"ERROR: Overflow\n"); - exit(1); - } -} - -static int -parse_nd(char *p) -{ - char ref_buffer[BUFFER_SIZE]; - if (!xml_get_attribute(p, "ref", ref_buffer, BUFFER_SIZE)) - return 0; - add_nd(p, atoi(ref_buffer)); - return 1; -} - - -static void -save_buffer(char *filename, struct buffer *b, long long offset) -{ - FILE *f; - f=fopen(filename,"rb+"); - if (! f) - f=fopen(filename,"wb+"); - - assert(f != NULL); - fseek(f, offset, SEEK_SET); - fwrite(b->base, b->size, 1, f); - fclose(f); -} - -static void -load_buffer(char *filename, struct buffer *b, long long offset, long long size) -{ - FILE *f; - long long len; - int ret; - if (b->base) - free(b->base); - b->malloced=0; - f=fopen(filename,"rb"); - fseek(f, 0, SEEK_END); - len=ftell(f); - if (offset+size > len) { - size=len-offset; - ret=1; - } - b->size=b->malloced=size; - fprintf(stderr,"reading %Ld bytes from %s at %Ld\n", b->size, filename, offset); - fseek(f, offset, SEEK_SET); - b->base=malloc(b->size); - assert(b->base != NULL); - fread(b->base, b->size, 1, f); - fclose(f); -} - -static int -phase1(FILE *in, FILE *out_ways, FILE *out_nodes, FILE *out_turn_restrictions) -{ - int size=BUFFER_SIZE; - char buffer[size]; - char *p; - sig_alrm(0); - while (fgets(buffer, size, in)) { - p=strchr(buffer,'<'); - if (! p) { - fprintf(stderr,"WARNING: wrong line %s\n", buffer); - continue; - } - if (!strncmp(p, "",7)) { - in_node=0; - end_node(out_nodes); - } else if (!strncmp(p, "",6)) { - in_way=0; - end_way(out_ways); - } else if (!strncmp(p, "",11)) { - in_relation=0; - end_relation(out_turn_restrictions); - } else if (!strncmp(p, "",6)) { - } else { - fprintf(stderr,"WARNING: unknown tag in %s\n", buffer); - } - } - sig_alrm(0); -#ifndef _WIN32 - alarm(0); -#endif - return 1; -} - -#ifdef HAVE_POSTGRESQL -static int -phase1_db(char *dbstr, FILE *out_ways, FILE *out_nodes) -{ - PGconn *conn; - PGresult *res,*node,*way,*tag; - int count,tagged,i,j,k; - long min, max, id, tag_id, node_id; - char query[256]; - - sig_alrm(0); - conn=PQconnectdb(dbstr); - if (! conn) { - fprintf(stderr,"Failed to connect to database with '%s'\n",dbstr); - exit(1); - } - res=PQexec(conn, "begin"); - if (! res) { - fprintf(stderr, "Cannot begin transaction: %s\n", PQerrorMessage(conn)); - PQclear(res); - exit(1); - } - res=PQexec(conn, "set transaction isolation level serializable"); - if (! res) { - fprintf(stderr, "Cannot set isolation level: %s\n", PQerrorMessage(conn)); - PQclear(res); - exit(1); - } - res=PQexec(conn, "declare node cursor for select id,x(coordinate),y(coordinate) from node order by id"); - if (! res) { - fprintf(stderr, "Cannot setup cursor for nodes: %s\n", PQerrorMessage(conn)); - PQclear(res); - exit(1); - } - res=PQexec(conn, "declare way cursor for select id from way order by id"); - if (! res) { - fprintf(stderr, "Cannot setup cursor for nodes: %s\n", PQerrorMessage(conn)); - PQclear(res); - exit(1); - } - res=PQexec(conn, "declare relation cursor for select id from relation order by id"); - if (! res) { - fprintf(stderr, "Cannot setup cursor for nodes: %s\n", PQerrorMessage(conn)); - PQclear(res); - exit(1); - } - for (;;) { - node=PQexec(conn, "fetch 100000 from node"); - if (! node) { - fprintf(stderr, "Cannot setup cursor for nodes: %s\n", PQerrorMessage(conn)); - PQclear(node); - exit(1); - } - count=PQntuples(node); - if (! count) - break; - min=atol(PQgetvalue(node, 0, 0)); - max=atol(PQgetvalue(node, count-1, 0)); - sprintf(query,"select node_id,name,value from node_tag where node_id >= %ld and node_id <= %ld order by node_id", min, max); - tag=PQexec(conn, query); - if (! tag) { - fprintf(stderr, "Cannot query node_tag: %s\n", PQerrorMessage(conn)); - exit(1); - } - j=0; - for (i = 0 ; i < count ; i++) { - id=atol(PQgetvalue(node, i, 0)); - add_node(id, atof(PQgetvalue(node, i, 1)), atof(PQgetvalue(node, i, 2))); - tagged=0; - in_node=1; - processed_nodes++; - while (j < PQntuples(tag)) { - tag_id=atol(PQgetvalue(tag, j, 0)); - if (tag_id == id) { - add_tag(PQgetvalue(tag, j, 1), PQgetvalue(tag, j, 2)); - tagged=1; - j++; - } - if (tag_id < id) - j++; - if (tag_id > id) - break; - } - if (tagged) - end_node(out_nodes); - in_node=0; - } - PQclear(tag); - PQclear(node); - } - for (;;) { - way=PQexec(conn, "fetch 100000 from way"); - if (! way) { - fprintf(stderr, "Cannot setup cursor for ways: %s\n", PQerrorMessage(conn)); - PQclear(node); - exit(1); - } - count=PQntuples(way); - if (! count) - break; - min=atol(PQgetvalue(way, 0, 0)); - max=atol(PQgetvalue(way, count-1, 0)); - sprintf(query,"select way_id,node_id from way_node where way_id >= %ld and way_id <= %ld order by way_id,sequence_id", min, max); - node=PQexec(conn, query); - if (! node) { - fprintf(stderr, "Cannot query way_node: %s\n", PQerrorMessage(conn)); - exit(1); - } - sprintf(query,"select way_id,name,value from way_tag where way_id >= %ld and way_id <= %ld order by way_id", min, max); - tag=PQexec(conn, query); - if (! tag) { - fprintf(stderr, "Cannot query way_tag: %s\n", PQerrorMessage(conn)); - exit(1); - } - j=0; - k=0; - for (i = 0 ; i < count ; i++) { - id=atol(PQgetvalue(way, i, 0)); - add_way(id); - tagged=0; - in_way=1; - processed_ways++; - while (k < PQntuples(node)) { - node_id=atol(PQgetvalue(node, k, 0)); - if (node_id == id) { - add_nd("",atol(PQgetvalue(node, k, 1))); - tagged=1; - k++; - } - if (node_id < id) - k++; - if (node_id > id) - break; - } - while (j < PQntuples(tag)) { - tag_id=atol(PQgetvalue(tag, j, 0)); - if (tag_id == id) { - add_tag(PQgetvalue(tag, j, 1), PQgetvalue(tag, j, 2)); - tagged=1; - j++; - } - if (tag_id < id) - j++; - if (tag_id > id) - break; - } - if (tagged) - end_way(out_ways); - in_way=0; - } - PQclear(tag); - PQclear(node); - PQclear(way); - } - - res=PQexec(conn, "commit"); - if (! res) { - fprintf(stderr, "Cannot commit transaction: %s\n", PQerrorMessage(conn)); - PQclear(res); - exit(1); - } - sig_alrm(0); -#ifndef _WIN32 - alarm(0); -#endif - return 1; -} -#endif - - -static void -phase1_map(struct map *map, FILE *out_ways, FILE *out_nodes) -{ - struct map_rect *mr=map_rect_new(map, NULL); - struct item *item; - int count,max=16384; - struct coord ca[max]; - struct attr attr; - - while ((item = map_rect_get_item(mr))) { - count=item_coord_get(item, ca, item->type < type_line ? 1: max); - item_bin_init(item_bin, item->type); - item_bin_add_coord(item_bin, ca, count); - while (item_attr_get(item, attr_any, &attr)) { - item_bin_add_attr(item_bin, &attr); - } - if (item->type >= type_line) - item_bin_write(item_bin, out_ways); - else - item_bin_write(item_bin, out_nodes); - } - map_rect_destroy(mr); -} - - -int bytes_read=0; - -static struct item_bin * -read_item(FILE *in) -{ - struct item_bin *ib=(struct item_bin *) buffer; - int r,s; - r=fread(ib, sizeof(*ib), 1, in); - if (r != 1) - return NULL; - bytes_read+=r; - assert((ib->len+1)*4 < sizeof(buffer)); - s=(ib->len+1)*4-sizeof(*ib); - r=fread(ib+1, s, 1, in); - if (r != 1) - return NULL; - bytes_read+=r; - return ib; -} - -static void -bbox_extend(struct coord *c, struct rect *r) -{ - if (c->x < r->l.x) - r->l.x=c->x; - if (c->y < r->l.y) - r->l.y=c->y; - if (c->x > r->h.x) - r->h.x=c->x; - if (c->y > r->h.y) - r->h.y=c->y; -} - -static void -bbox(struct coord *c, int count, struct rect *r) -{ - if (! count) - return; - r->l=*c; - r->h=*c; - while (--count) { - c++; - bbox_extend(c, r); - } -} - -static int -contains_bbox(int xl, int yl, int xh, int yh, struct rect *r) -{ - if (r->h.x < xl || r->h.x > xh) { - return 0; - } - if (r->l.x > xh || r->l.x < xl) { - return 0; - } - if (r->h.y < yl || r->h.y > yh) { - return 0; - } - if (r->l.y > yh || r->l.y < yl) { - return 0; - } - return 1; - -} -struct rect world_bbox = { - { -20000000, -20000000}, - { 20000000, 20000000}, -}; - -int overlap=1; - -static int -tile(struct rect *r, char *suffix, char *ret, int max, int overlap, struct rect *tr) -{ - int x0,x2,x4; - int y0,y2,y4; - int xo,yo; - int i; - x0=world_bbox.l.x; - y0=world_bbox.l.y; - x4=world_bbox.h.x; - y4=world_bbox.h.y; - for (i = 0 ; i < max ; i++) { - x2=(x0+x4)/2; - y2=(y0+y4)/2; - xo=(x4-x0)*overlap/100; - yo=(y4-y0)*overlap/100; - if ( contains_bbox(x0,y0,x2+xo,y2+yo,r)) { - strcat(ret,"d"); - x4=x2+xo; - y4=y2+yo; - } else if (contains_bbox(x2-xo,y0,x4,y2+yo,r)) { - strcat(ret,"c"); - x0=x2-xo; - y4=y2+yo; - } else if (contains_bbox(x0,y2-yo,x2+xo,y4,r)) { - strcat(ret,"b"); - x4=x2+xo; - y0=y2-yo; - } else if (contains_bbox(x2-xo,y2-yo,x4,y4,r)) { - strcat(ret,"a"); - x0=x2-xo; - y0=y2-yo; - } else - break; - } - if (tr) { - tr->l.x=x0; - tr->l.y=y0; - tr->h.x=x4; - tr->h.y=y4; - } - if (suffix) - strcat(ret,suffix); - return i; -} - -static void -tile_bbox(char *tile, struct rect *r, int overlap) -{ - struct coord c; - int xo,yo; - *r=world_bbox; - while (*tile) { - c.x=(r->l.x+r->h.x)/2; - c.y=(r->l.y+r->h.y)/2; - xo=(r->h.x-r->l.x)*overlap/100; - yo=(r->h.y-r->l.y)*overlap/100; - switch (*tile) { - case 'a': - r->l.x=c.x-xo; - r->l.y=c.y-yo; - break; - case 'b': - r->h.x=c.x+xo; - r->l.y=c.y-yo; - break; - case 'c': - r->l.x=c.x-xo; - r->h.y=c.y+yo; - break; - case 'd': - r->h.x=c.x+xo; - r->h.y=c.y+yo; - break; - } - tile++; - } -} - -static int -tile_len(char *tile) -{ - int ret=0; - while (tile[0] >= 'a' && tile[0] <= 'd') { - tile++; - ret++; - } - return ret; -} - -static int -clipcode(struct coord *p, struct rect *r) -{ - int code=0; - if (p->x < r->l.x) - code=1; - if (p->x > r->h.x) - code=2; - if (p->y < r->l.y) - code |=4; - if (p->y > r->h.y) - code |=8; - return code; -} - - -static int -clip_line_code(struct coord *p1, struct coord *p2, struct rect *r) -{ - int code1,code2,ret=1; - int dx,dy; - code1=clipcode(p1, r); - if (code1) - ret |= 2; - code2=clipcode(p2, r); - if (code2) - ret |= 4; - dx=p2->x-p1->x; - dy=p2->y-p1->y; - while (code1 || code2) { - if (code1 & code2) - return 0; - if (code1 & 1) { - p1->y+=(r->l.x-p1->x)*dy/dx; - p1->x=r->l.x; - } else if (code1 & 2) { - p1->y+=(r->h.x-p1->x)*dy/dx; - p1->x=r->h.x; - } else if (code1 & 4) { - p1->x+=(r->l.y-p1->y)*dx/dy; - p1->y=r->l.y; - } else if (code1 & 8) { - p1->x+=(r->h.y-p1->y)*dx/dy; - p1->y=r->h.y; - } - code1=clipcode(p1, r); - if (code1 & code2) - return 0; - if (code2 & 1) { - p2->y+=(r->l.x-p2->x)*dy/dx; - p2->x=r->l.x; - } else if (code2 & 2) { - p2->y+=(r->h.x-p2->x)*dy/dx; - p2->x=r->h.x; - } else if (code2 & 4) { - p2->x+=(r->l.y-p2->y)*dx/dy; - p2->y=r->l.y; - } else if (code2 & 8) { - p2->x+=(r->h.y-p2->y)*dx/dy; - p2->y=r->h.y; - } - code2=clipcode(p2, r); - } - if (p1->x == p2->x && p1->y == p2->y) - ret=0; - return ret; -} - -static void item_bin_write_clipped(struct item_bin *ib, struct tile_parameter *param, struct item_bin_sink *out); - -static void -clip_line(struct item_bin *ib, struct rect *r, struct tile_parameter *param, struct item_bin_sink *out) -{ - char buffer[ib->len*4+32]; - struct item_bin *ib_new=(struct item_bin *)buffer; - struct coord *pa=(struct coord *)(ib+1); - int count=ib->clen/2; - struct coord p1,p2; - int i,code; - item_bin_init(ib_new, ib->type); - for (i = 0 ; i < count ; i++) { - if (i) { - p1.x=pa[i-1].x; - p1.y=pa[i-1].y; - p2.x=pa[i].x; - p2.y=pa[i].y; - /* 0 = invisible, 1 = completely visible, 3 = start point clipped, 5 = end point clipped, 7 both points clipped */ - code=clip_line_code(&p1, &p2, r); -#if 1 - if (((code == 1 || code == 5) && ib_new->clen == 0) || (code & 2)) { - item_bin_add_coord(ib_new, &p1, 1); - } - if (code) { - item_bin_add_coord(ib_new, &p2, 1); - } - if (i == count-1 || (code & 4)) { - if (ib_new->clen) - item_bin_write_clipped(ib_new, param, out); - item_bin_init(ib_new, ib->type); - } -#else - if (code) { - item_bin_init(ib_new, ib->type); - item_bin_add_coord(ib_new, &p1, 1); - item_bin_add_coord(ib_new, &p2, 1); - item_bin_write_clipped(ib_new, param, out); - } -#endif - } - } -} - -static int -is_inside(struct coord *p, struct rect *r, int edge) -{ - switch(edge) { - case 0: - return p->x >= r->l.x; - case 1: - return p->x <= r->h.x; - case 2: - return p->y >= r->l.y; - case 3: - return p->y <= r->h.y; - default: - return 0; - } -} - -static void -poly_intersection(struct coord *p1, struct coord *p2, struct rect *r, int edge, struct coord *ret) -{ - int dx=p2->x-p1->x; - int dy=p2->y-p1->y; - switch(edge) { - case 0: - ret->y=p1->y+(r->l.x-p1->x)*dy/dx; - ret->x=r->l.x; - break; - case 1: - ret->y=p1->y+(r->h.x-p1->x)*dy/dx; - ret->x=r->h.x; - break; - case 2: - ret->x=p1->x+(r->l.y-p1->y)*dx/dy; - ret->y=r->l.y; - break; - case 3: - ret->x=p1->x+(r->h.y-p1->y)*dx/dy; - ret->y=r->h.y; - break; - } -} - -static void -clip_polygon(struct item_bin *ib, struct rect *r, struct tile_parameter *param, struct item_bin_sink *out) -{ - int count_in=ib->clen/2; - struct coord *pin,*p,*s,pi; - char buffer1[ib->len*4+ib->clen*7+32]; - struct item_bin *ib1=(struct item_bin *)buffer1; - char buffer2[ib->len*4+ib->clen*7+32]; - struct item_bin *ib2=(struct item_bin *)buffer2; - struct item_bin *ib_in,*ib_out; - int edge,i; - ib_out=ib1; - ib_in=ib; - for (edge = 0 ; edge < 4 ; edge++) { - count_in=ib_in->clen/2; - pin=(struct coord *)(ib_in+1); - p=pin; - s=pin+count_in-1; - item_bin_init(ib_out, ib_in->type); - for (i = 0 ; i < count_in ; i++) { - if (is_inside(p, r, edge)) { - if (! is_inside(s, r, edge)) { - poly_intersection(s,p,r,edge,&pi); - item_bin_add_coord(ib_out, &pi, 1); - } - item_bin_add_coord(ib_out, p, 1); - } else { - if (is_inside(s, r, edge)) { - poly_intersection(p,s,r,edge,&pi); - item_bin_add_coord(ib_out, &pi, 1); - } - } - s=p; - p++; - } - if (ib_in == ib1) { - ib_in=ib2; - ib_out=ib1; - } else { - ib_in=ib1; - ib_out=ib2; - } - } - if (ib_in->clen) - item_bin_write_clipped(ib_in, param, out); -} - -static void -item_bin_bbox(struct item_bin *ib, struct rect *r) -{ - struct coord c; - item_bin_add_coord(ib, &r->l, 1); - c.x=r->h.x; - c.y=r->l.y; - item_bin_add_coord(ib, &c, 1); - item_bin_add_coord(ib, &r->h, 1); - c.x=r->l.x; - c.y=r->h.y; - item_bin_add_coord(ib, &c, 1); - item_bin_add_coord(ib, &r->l, 1); -} - -static int -bbox_marker_process(struct item_bin_sink_func *func, struct item_bin *ib, struct tile_data *tile_data) -{ - char buffer2[1024]; - struct item_bin *ibb=(struct item_bin *)buffer2; - struct item_bin_sink_func *out=func->priv_data[0]; - item_bin_init(ibb, type_border_country); - item_bin_bbox(ibb, &tile_data->tile_bbox); - item_bin_write_to_sink_func(ibb, out, NULL); - return 0; -} - -static struct item_bin_sink_func * -bbox_marker_new(struct item_bin_sink_func *func) -{ - struct item_bin_sink_func *bbox_marker=item_bin_sink_func_new(bbox_marker_process); - bbox_marker->priv_data[0]=func; - return bbox_marker; -} - -static int -bbox_marker_finish(struct item_bin_sink_func *bbox_marker) -{ - item_bin_sink_func_destroy(bbox_marker); - return 0; -} - - -static void -item_bin_write_clipped(struct item_bin *ib, struct tile_parameter *param, struct item_bin_sink *out) -{ - struct tile_data tile_data; - int i; - bbox((struct coord *)(ib+1), ib->clen/2, &tile_data.item_bbox); - tile_data.buffer[0]='\0'; - tile_data.tile_depth=tile(&tile_data.item_bbox, NULL, tile_data.buffer, param->max, param->overlap, &tile_data.tile_bbox); - if (tile_data.tile_depth == param->max || tile_data.tile_depth >= param->min) { - item_bin_write_to_sink(ib, out, &tile_data); - return; - } - for (i = 0 ; i < 4 ; i++) { - struct rect clip_rect; - tile_data.buffer[tile_data.tile_depth]='a'+i; - tile_data.buffer[tile_data.tile_depth+1]='\0'; - tile_bbox(tile_data.buffer, &clip_rect, param->overlap); - if (ib->type < type_area) - clip_line(ib, &clip_rect, param, out); - else - clip_polygon(ib, &clip_rect, param, out); - } -} - -GHashTable *tile_hash; -GHashTable *tile_hash2; - -static void -tile_extend(char *tile, struct item_bin *ib, GList **tiles_list) -{ - struct tile_head *th=NULL; - if (debug_tile(tile)) - fprintf(stderr,"Tile:Writing %d bytes to '%s' (%p,%p) 0x%x %Ld\n", (ib->len+1)*4, tile, g_hash_table_lookup(tile_hash, tile), tile_hash2 ? g_hash_table_lookup(tile_hash2, tile) : NULL, ib->type, item_bin_get_id(ib)); - if (tile_hash2) - th=g_hash_table_lookup(tile_hash2, tile); - if (!th) - th=g_hash_table_lookup(tile_hash, tile); - if (! th) { - th=malloc(sizeof(struct tile_head)+ sizeof( char* ) ); - assert(th != NULL); - // strcpy(th->subtiles, tile); - th->num_subtiles=1; - th->total_size=0; - th->total_size_used=0; - th->zipnum=0; - th->zip_data=NULL; - th->name=string_hash_lookup(tile); - *th_get_subtile( th, 0 ) = th->name; - - if (tile_hash2) - g_hash_table_insert(tile_hash2, string_hash_lookup( th->name ), th); - if (tiles_list) - *tiles_list=g_list_append(*tiles_list, string_hash_lookup( th->name ) ); - processed_tiles++; - if (debug_tile(tile)) - fprintf(stderr,"new '%s'\n", tile); - } - th->total_size+=ib->len*4+4; - if (debug_tile(tile)) - fprintf(stderr,"New total size of %s(%p):%d\n", th->name, th, th->total_size); - g_hash_table_insert(tile_hash, string_hash_lookup( th->name ), th); -} - -static int -tile_data_size(char *tile) -{ - struct tile_head *th; - th=g_hash_table_lookup(tile_hash, tile); - if (! th) - return 0; - return th->total_size; -} - -static int -merge_tile(char *base, char *sub) -{ - struct tile_head *thb, *ths; - thb=g_hash_table_lookup(tile_hash, base); - ths=g_hash_table_lookup(tile_hash, sub); - if (! ths) - return 0; - if (debug_tile(base) || debug_tile(sub)) - fprintf(stderr,"merging '%s'(%p) (%d) with '%s'(%p) (%d)\n", base, thb, thb ? thb->total_size : 0, sub, ths, ths->total_size); - if (! thb) { - thb=ths; - g_hash_table_remove(tile_hash, sub); - thb->name=string_hash_lookup(base); - g_hash_table_insert(tile_hash, string_hash_lookup( thb->name ), thb); - - } else { - thb=realloc(thb, sizeof(struct tile_head)+( ths->num_subtiles+thb->num_subtiles ) * sizeof( char*) ); - assert(thb != NULL); - memcpy( th_get_subtile( thb, thb->num_subtiles ), th_get_subtile( ths, 0 ), ths->num_subtiles * sizeof( char*) ); - thb->num_subtiles+=ths->num_subtiles; - thb->total_size+=ths->total_size; - g_hash_table_insert(tile_hash, string_hash_lookup( thb->name ), thb); - g_hash_table_remove(tile_hash, sub); - g_free(ths); - } - return 1; -} - - -static void -get_tiles_list_func(char *key, struct tile_head *th, GList **list) -{ - *list=g_list_prepend(*list, key); -} - -static GList * -get_tiles_list(void) -{ - GList *ret=NULL; - g_hash_table_foreach(tile_hash, (GHFunc)get_tiles_list_func, &ret); - return ret; -} - -#if 0 -static void -write_tile(char *key, struct tile_head *th, gpointer dummy) -{ - FILE *f; - char buffer[1024]; - fprintf(stderr,"DEBUG: Writing %s\n", key); - strcpy(buffer,"tiles/"); - strcat(buffer,key); -#if 0 - strcat(buffer,".bin"); -#endif - f=fopen(buffer, "wb+"); - while (th) { - fwrite(th->data, th->size, 1, f); - th=th->next; - } - fclose(f); -} -#endif - -static void -write_item(char *tile, struct item_bin *ib, FILE *reference) -{ - struct tile_head *th; - int size; - - th=g_hash_table_lookup(tile_hash2, tile); - if (debug_itembin(ib)) { - fprintf(stderr,"tile head %p\n",th); - } - if (! th) - th=g_hash_table_lookup(tile_hash, tile); - if (th) { - if (debug_itembin(ib)) { - fprintf(stderr,"Match %s %d %s\n",tile,th->process,th->name); - dump_itembin(ib); - } - if (th->process != 0 && th->process != 1) { - fprintf(stderr,"error with tile '%s' of length %d\n", tile, (int)strlen(tile)); - abort(); - } - if (! th->process) { - if (reference) - fseek(reference, 8, SEEK_CUR); - return; - } - if (debug_tile(tile)) - fprintf(stderr,"Data:Writing %d bytes to '%s' (%p,%p) 0x%x\n", (ib->len+1)*4, tile, g_hash_table_lookup(tile_hash, tile), tile_hash2 ? g_hash_table_lookup(tile_hash2, tile) : NULL, ib->type); - size=(ib->len+1)*4; - if (th->total_size_used+size > th->total_size) { - fprintf(stderr,"Overflow in tile %s (used %d max %d item %d)\n", tile, th->total_size_used, th->total_size, size); - exit(1); - return; - } - if (reference) { - fwrite(&th->zipnum, sizeof(th->zipnum), 1, reference); - fwrite(&th->total_size_used, sizeof(th->total_size_used), 1, reference); - } - memcpy(th->zip_data+th->total_size_used, ib, size); - th->total_size_used+=size; - } else { - fprintf(stderr,"no tile hash found for %s\n", tile); - exit(1); - } -} - -static void -write_item_part(FILE *out, FILE *out_index, FILE *out_graph, struct item_bin *orig, int first, int last, long long *last_id) -{ - struct item_bin new; - struct coord *c=(struct coord *)(orig+1); - char *attr=(char *)(c+orig->clen/2); - int attr_len=orig->len-orig->clen-2; - processed_ways++; - new.type=orig->type; - new.clen=(last-first+1)*2; - new.len=new.clen+attr_len+2; - if (out_index) { - long long idx[2]; - idx[0]=item_bin_get_wayid(orig); - idx[1]=ftell(out); - if (way_hash) { - if (!(g_hash_table_lookup_extended(way_hash, (gpointer)(long)idx[0], NULL, NULL))) - g_hash_table_insert(way_hash, (gpointer)(long)idx[0], (gpointer)(long)idx[1]); - } else { - if (!last_id || *last_id != idx[0]) - fwrite(idx, sizeof(idx), 1, out_index); - if (last_id) - *last_id=idx[0]; - } - - } -#if 0 - fprintf(stderr,"first %d last %d type 0x%x len %d clen %d attr_len %d\n", first, last, new.type, new.len, new.clen, attr_len); -#endif - fwrite(&new, sizeof(new), 1, out); - fwrite(c+first, new.clen*4, 1, out); - fwrite(attr, attr_len*4, 1, out); -#if 0 - fwrite(&new, sizeof(new), 1, out_graph); - fwrite(c+first, new.clen*4, 1, out_graph); - fwrite(attr, attr_len*4, 1, out_graph); -#endif -} - -static int -phase2(FILE *in, FILE *out, FILE *out_index, FILE *out_graph, FILE *out_coastline, int final) -{ - struct coord *c; - int i,ccount,last,remaining; - osmid ndref; - struct item_bin *ib; - struct node_item *ni; - long long last_id=0; - - processed_nodes=processed_nodes_out=processed_ways=processed_relations=processed_tiles=0; - sig_alrm(0); - while ((ib=read_item(in))) { -#if 0 - fprintf(stderr,"type 0x%x len %d clen %d\n", ib->type, ib->len, ib->clen); -#endif - ccount=ib->clen/2; - if (ccount <= 1) - continue; - c=(struct coord *)(ib+1); - last=0; - for (i = 0 ; i < ccount ; i++) { - if (IS_REF(c[i])) { - ndref=REF(c[i]); - ni=node_item_get(ndref); - if (ni) { - c[i]=ni->c; - if (ni->ref_way > 1 && i != 0 && i != ccount-1 && i != last && item_get_default_flags(ib->type)) { - write_item_part(out, out_index, out_graph, ib, last, i, &last_id); - last=i; - } - } else if (final) { - osm_warning("way",item_bin_get_wayid(ib),0,"Non-existing reference to "); - osm_warning("node",ndref,1,"\n"); - remaining=(ib->len+1)*4-sizeof(struct item_bin)-i*sizeof(struct coord); - memmove(&c[i], &c[i+1], remaining); - ib->clen-=2; - ib->len-=2; - i--; - ccount--; - } - } - } - if (ccount) { - write_item_part(out, out_index, out_graph, ib, last, ccount-1, &last_id); - if (final && ib->type == type_water_line && out_coastline) { - write_item_part(out_coastline, NULL, NULL, ib, last, ccount-1, NULL); - } - } - } - sig_alrm(0); -#ifndef _WIN32 - alarm(0); -#endif - return 0; -} - -struct tile_info { - int write; - int maxlen; - char *suffix; - GList **tiles_list; - FILE *tilesdir_out; -}; - -struct zip_info { - int zipnum; - int dir_size; - long long offset; - int compression_level; - int maxnamelen; - FILE *res; - FILE *index; - FILE *dir; -}; - -static void write_zipmember(struct zip_info *zip_info, char *name, int filelen, char *data, int data_size); - -static void -tile_write_item_to_tile(struct tile_info *info, struct item_bin *ib, FILE *reference, char *name) -{ - if (info->write) - write_item(name, ib, reference); - else - tile_extend(name, ib, info->tiles_list); -} - -static void -tile_write_item_minmax(struct tile_info *info, struct item_bin *ib, FILE *reference, int min, int max) -{ - struct rect r; - char buffer[1024]; - bbox((struct coord *)(ib+1), ib->clen/2, &r); - buffer[0]='\0'; - tile(&r, info->suffix, buffer, max, overlap, NULL); - tile_write_item_to_tile(info, ib, reference, buffer); -} - -static void -phase34_process_file(struct tile_info *info, FILE *in, FILE *reference) -{ - struct item_bin *ib; - int max; - - while ((ib=read_item(in))) { - if (ib->type < 0x80000000) - processed_nodes++; - else - processed_ways++; - max=14; - switch (ib->type) { - case type_town_label_1e7: - case type_town_label_5e6: - case type_town_label_2e6: - case type_town_label_1e6: - case type_town_label_5e5: - case type_district_label_1e7: - case type_district_label_5e6: - case type_district_label_2e6: - case type_district_label_1e6: - case type_district_label_5e5: - max=6; - break; - case type_town_label_2e5: - case type_town_label_1e5: - case type_district_label_2e5: - case type_district_label_1e5: - case type_street_n_lanes: - case type_highway_city: - case type_highway_land: - case type_ramp: - max=8; - break; - case type_town_label_5e4: - case type_town_label_2e4: - case type_town_label_1e4: - case type_district_label_5e4: - case type_district_label_2e4: - case type_district_label_1e4: - max=9; - break; - case type_town_label_5e3: - case type_town_label_2e3: - case type_town_label_1e3: - case type_district_label_5e3: - case type_district_label_2e3: - case type_district_label_1e3: - case type_street_3_city: - case type_street_4_city: - case type_street_3_land: - case type_street_4_land: - max=12; - break; - default: - break; - } - tile_write_item_minmax(info, ib, reference, 0, max); - } -} - -static void -index_init(struct zip_info *info, int version) -{ - item_bin_init(item_bin, type_map_information); - item_bin_add_attr_int(item_bin, attr_version, version); - item_bin_write(item_bin, info->index); -} - -static void -index_submap_add(struct tile_info *info, struct tile_head *th) -{ - int tlen=tile_len(th->name); - int len=tlen; - char index_tile[len+1+strlen(suffix)]; - struct rect r; - - strcpy(index_tile, th->name); - if (len > 6) - len=6; - else - len=0; - index_tile[len]=0; - if (tlen) - strcat(index_tile, suffix); - tile_bbox(th->name, &r, overlap); - - item_bin_init(item_bin, type_submap); - item_bin_add_coord_rect(item_bin, &r); - item_bin_add_attr_range(item_bin, attr_order, (tlen > 4)?tlen-4 : 0, 255); - item_bin_add_attr_int(item_bin, attr_zipfile_ref, th->zipnum); - tile_write_item_to_tile(info, item_bin, NULL, index_tile); -} - -static int -add_tile_hash(struct tile_head *th) -{ - int idx,len,maxnamelen=0; - char **data; - -#if 0 - g_hash_table_insert(tile_hash2, string_hash_lookup( th->name ), th); -#endif - for( idx = 0; idx < th->num_subtiles; idx++ ) { - - data = th_get_subtile( th, idx ); - - if (debug_tile(((char *)data)) || debug_tile(th->name)) { - fprintf(stderr,"Parent for '%s' is '%s'\n", *data, th->name); - } - - g_hash_table_insert(tile_hash2, *data, th); - - len = strlen( *data ); - - if (len > maxnamelen) { - maxnamelen=len; - } - } - return maxnamelen; -} - - -static int -create_tile_hash(void) -{ - struct tile_head *th; - int len,maxnamelen=0; - - tile_hash2=g_hash_table_new(g_str_hash, g_str_equal); - th=tile_head_root; - while (th) { - len=add_tile_hash(th); - if (len > maxnamelen) - maxnamelen=len; - th=th->next; - } - return maxnamelen; -} - -static void -create_tile_hash_list(GList *list) -{ - GList *next; - struct tile_head *th; - - tile_hash2=g_hash_table_new(g_str_hash, g_str_equal); - - next=g_list_first(list); - while (next) { - th=g_hash_table_lookup(tile_hash, next->data); - if (!th) { - fprintf(stderr,"No tile found for '%s'\n", (char *)(next->data)); - } - add_tile_hash(th); - next=g_list_next(next); - } -} - -#if 0 -static void -destroy_tile_hash(void) -{ - g_hash_table_destroy(tile_hash2); - tile_hash2=NULL; -} -#endif - -static void write_countrydir(struct zip_info *zip_info); - -static void -write_tilesdir(struct tile_info *info, struct zip_info *zip_info, FILE *out) -{ - int idx,len,maxlen; - GList *next,*tiles_list; - char **data; - struct tile_head *th,**last=NULL; - - tiles_list=get_tiles_list(); - info->tiles_list=&tiles_list; - if (phase == 3) - create_tile_hash_list(tiles_list); - next=g_list_first(tiles_list); - last=&tile_head_root; - maxlen=info->maxlen; - if (! maxlen) { - while (next) { - if (strlen(next->data) > maxlen) - maxlen=strlen(next->data); - next=g_list_next(next); - } - } - len=maxlen; - while (len >= 0) { -#if 0 - fprintf(stderr,"PROGRESS: collecting tiles with len=%d\n", len); -#endif - next=g_list_first(tiles_list); - while (next) { - if (strlen(next->data) == len) { - th=g_hash_table_lookup(tile_hash, next->data); - if (phase == 3) { - *last=th; - last=&th->next; - th->next=NULL; - th->zipnum=zip_info->zipnum; - fprintf(out,"%s:%d",(char *)next->data,th->total_size); - - for ( idx = 0; idx< th->num_subtiles; idx++ ){ - data= th_get_subtile( th, idx ); - fprintf(out,":%s", *data); - } - - fprintf(out,"\n"); - } - if (th->name[0]) - index_submap_add(info, th); - zip_info->zipnum++; - processed_tiles++; - } - next=g_list_next(next); - } - len--; - } -} - -static void -merge_tiles(struct tile_info *info) -{ - struct tile_head *th; - char basetile[1024]; - char subtile[1024]; - GList *tiles_list_sorted,*last; - int i,i_min,len,size_all,size[5],size_min,work_done; - long long zip_size; - - do { - tiles_list_sorted=get_tiles_list(); - fprintf(stderr,"PROGRESS: sorting %d tiles\n", g_list_length(tiles_list_sorted)); - tiles_list_sorted=g_list_sort(tiles_list_sorted, (GCompareFunc)strcmp); - fprintf(stderr,"PROGRESS: sorting %d tiles done\n", g_list_length(tiles_list_sorted)); - last=g_list_last(tiles_list_sorted); - zip_size=0; - while (last) { - th=g_hash_table_lookup(tile_hash, last->data); - zip_size+=th->total_size; - last=g_list_previous(last); - } - last=g_list_last(tiles_list_sorted); - work_done=0; - while (last) { - processed_tiles++; - len=tile_len(last->data); - if (len >= 1) { - strcpy(basetile,last->data); - basetile[len-1]='\0'; - strcat(basetile, info->suffix); - strcpy(subtile,last->data); - for (i = 0 ; i < 4 ; i++) { - subtile[len-1]='a'+i; - size[i]=tile_data_size(subtile); - } - size[4]=tile_data_size(basetile); - size_all=size[0]+size[1]+size[2]+size[3]+size[4]; - if (size_all < 65536 && size_all > 0 && size_all != size[4]) { - for (i = 0 ; i < 4 ; i++) { - subtile[len-1]='a'+i; - work_done+=merge_tile(basetile, subtile); - } - } else { - for (;;) { - size_min=size_all; - i_min=-1; - for (i = 0 ; i < 4 ; i++) { - if (size[i] && size[i] < size_min) { - size_min=size[i]; - i_min=i; - } - } - if (i_min == -1) - break; - if (size[4]+size_min >= 65536) - break; - subtile[len-1]='a'+i_min; - work_done+=merge_tile(basetile, subtile); - size[4]+=size[i_min]; - size[i_min]=0; - } - } - } - last=g_list_previous(last); - } - g_list_free(tiles_list_sorted); - fprintf(stderr,"PROGRESS: merged %d tiles\n", work_done); - } while (work_done); -} - -static void -index_country_add(struct zip_info *info, int country_id, int zipnum) -{ - item_bin_init(item_bin, type_countryindex); - item_bin_add_attr_int(item_bin, attr_country_id, country_id); - item_bin_add_attr_int(item_bin, attr_zipfile_ref, zipnum); - item_bin_write(item_bin, info->index); -} - -struct aux_tile { - char *name; - char *filename; - int size; -}; - -static int -add_aux_tile(struct zip_info *zip_info, char *name, char *filename, int size) -{ - struct aux_tile *at; - GList *l; - l=aux_tile_list; - while (l) { - at=l->data; - if (!strcmp(at->name, name)) { - fprintf(stderr,"exists %s vs %s\n",at->name, name); - return -1; - } - l=g_list_next(l); - } - at=g_new0(struct aux_tile, 1); - at->name=g_strdup(name); - at->filename=g_strdup(filename); - at->size=size; - aux_tile_list=g_list_append(aux_tile_list, at); - return zip_info->zipnum++; -} - -static int -write_aux_tiles(struct zip_info *zip_info) -{ - GList *l=aux_tile_list; - struct aux_tile *at; - char *buffer; - FILE *f; - int count=0; - - while (l) { - at=l->data; - buffer=malloc(at->size); - assert(buffer != NULL); - f=fopen(at->filename,"rb"); - assert(f != NULL); - fread(buffer, at->size, 1, f); - fclose(f); - write_zipmember(zip_info, at->name, zip_info->maxnamelen, buffer, at->size); - free(buffer); - count++; - l=g_list_next(l); - zip_info->zipnum++; - } - return count; -} - -static void -write_countrydir(struct zip_info *zip_info) -{ - int i,zipnum,num; - int max=11; - char tilename[32]; - char filename[32]; - char suffix[32]; - struct country_table *co; - for (i = 0 ; i < sizeof(country_table)/sizeof(struct country_table) ; i++) { - co=&country_table[i]; - if (co->size) { - num=0; - do { - tilename[0]='\0'; - sprintf(suffix,"s%d", num); - num++; - tile(&co->r, suffix, tilename, max, overlap, NULL); - sprintf(filename,"country_%d.bin", co->countryid); - zipnum=add_aux_tile(zip_info, tilename, filename, co->size); - } while (zipnum == -1); - index_country_add(zip_info,co->countryid,zipnum); - } - } -} - -static void -write_index(struct zip_info *info) -{ - int size=ftell(info->index); - char buffer[size]; - - fseek(info->index, 0, SEEK_SET); - fread(buffer, size, 1, info->index); - write_zipmember(info, "index", strlen("index"), buffer, size); - info->zipnum++; -} - -static void -remove_countryfiles(void) -{ - int i; - char filename[32]; - struct country_table *co; - - for (i = 0 ; i < sizeof(country_table)/sizeof(struct country_table) ; i++) { - co=&country_table[i]; - if (co->size) { - sprintf(filename,"country_%d.bin", co->countryid); - unlink(filename); - } - } -} - -static int -phase34(struct tile_info *info, struct zip_info *zip_info, FILE **in, FILE **reference, int in_count) -{ - int i; - - processed_nodes=processed_nodes_out=processed_ways=processed_relations=processed_tiles=0; - bytes_read=0; - sig_alrm(0); - if (! info->write) - tile_hash=g_hash_table_new(g_str_hash, g_str_equal); - for (i = 0 ; i < in_count ; i++) { - if (in[i]) - phase34_process_file(info, in[i], reference ? reference[i]:NULL); - } - if (! info->write) - merge_tiles(info); - sig_alrm(0); -#ifndef _WIN32 - alarm(0); -#endif - write_tilesdir(info, zip_info, info->tilesdir_out); - - return 0; - -} - - -static void -dump_itembin(struct item_bin *ib) -{ - item_bin_dump(ib, stdout); -} - -static void -dump(FILE *in) -{ - struct item_bin *ib; - while ((ib=read_item(in))) { - dump_itembin(ib); - } -} - -static int -phase4(FILE **in, int in_count, char *suffix, FILE *tilesdir_out, struct zip_info *zip_info) -{ - struct tile_info info; - info.write=0; - info.maxlen=0; - info.suffix=suffix; - info.tiles_list=NULL; - info.tilesdir_out=tilesdir_out; - return phase34(&info, zip_info, in, NULL, in_count); -} - -static int -compress2_int(Byte *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level) -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit2(&stream, level, Z_DEFLATED, -15, 9, Z_DEFAULT_STRATEGY); - if (err != Z_OK) return err; - - err = deflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - deflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - *destLen = stream.total_out; - - err = deflateEnd(&stream); - return err; -} - -static void -write_zipmember(struct zip_info *zip_info, char *name, int filelen, char *data, int data_size) -{ - struct zip_lfh lfh = { - 0x04034b50, - 0x0a, - 0x0, - 0x0, - 0xbe2a, - 0x5d37, - 0x0, - 0x0, - 0x0, - filelen, - 0x0, - }; - struct zip_cd cd = { - 0x02014b50, - 0x17, - 0x00, - 0x0a, - 0x00, - 0x0000, - 0x0, - 0xbe2a, - 0x5d37, - 0x0, - 0x0, - 0x0, - filelen, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0, - zip_info->offset, - }; - char filename[filelen+1]; - int error,crc,len,comp_size=data_size; - uLongf destlen=data_size+data_size/500+12; - char *compbuffer; - - compbuffer = malloc(destlen); - if (!compbuffer) { - fprintf(stderr, "No more memory.\n"); - exit (1); - } - - crc=crc32(0, NULL, 0); - crc=crc32(crc, (unsigned char *)data, data_size); -#ifdef HAVE_ZLIB - if (zip_info->compression_level) { - error=compress2_int((Byte *)compbuffer, &destlen, (Bytef *)data, data_size, zip_info->compression_level); - if (error == Z_OK) { - if (destlen < data_size) { - data=compbuffer; - comp_size=destlen; - } - } else { - fprintf(stderr,"compress2 returned %d\n", error); - } - } -#endif - lfh.zipcrc=crc; - lfh.zipsize=comp_size; - lfh.zipuncmp=data_size; - lfh.zipmthd=zip_info->compression_level ? 8:0; - cd.zipccrc=crc; - cd.zipcsiz=comp_size; - cd.zipcunc=data_size; - cd.zipcmthd=zip_info->compression_level ? 8:0; - strcpy(filename, name); - len=strlen(filename); - while (len < filelen) { - filename[len++]='_'; - } - filename[filelen]='\0'; - fwrite(&lfh, sizeof(lfh), 1, zip_info->res); - fwrite(filename, filelen, 1, zip_info->res); - fwrite(data, comp_size, 1, zip_info->res); - zip_info->offset+=sizeof(lfh)+filelen+comp_size; - fwrite(&cd, sizeof(cd), 1, zip_info->dir); - fwrite(filename, filelen, 1, zip_info->dir); - zip_info->dir_size+=sizeof(cd)+filelen; - - free(compbuffer); -} - -static int -process_slice(FILE **in, FILE **reference, int in_count, long long size, char *suffix, struct zip_info *zip_info) -{ - struct tile_head *th; - char *slice_data,*zip_data; - int zipfiles=0; - struct tile_info info; - int i; - - slice_data=malloc(size); - assert(slice_data != NULL); - zip_data=slice_data; - th=tile_head_root; - while (th) { - if (th->process) { - th->zip_data=zip_data; - zip_data+=th->total_size; - } - th=th->next; - } - for (i = 0 ; i < in_count ; i++) { - if (in[i]) - fseek(in[i], 0, SEEK_SET); - if (reference && reference[i]) { - fseek(reference[i], 0, SEEK_SET); - } - } - info.write=1; - info.maxlen=zip_info->maxnamelen; - info.suffix=suffix; - info.tiles_list=NULL; - info.tilesdir_out=NULL; - phase34(&info, zip_info, in, reference, in_count); - - th=tile_head_root; - while (th) { - if (th->process) { - if (th->name[0]) { - if (th->total_size != th->total_size_used) { - fprintf(stderr,"Size error '%s': %d vs %d\n", th->name, th->total_size, th->total_size_used); - exit(1); - } - write_zipmember(zip_info, th->name, zip_info->maxnamelen, th->zip_data, th->total_size); - zipfiles++; - } else - fwrite(th->zip_data, th->total_size, 1, zip_info->index); - } - th=th->next; - } - free(slice_data); - - return zipfiles; -} - -static void -cat(FILE *in, FILE *out) -{ - size_t size; - char buffer[4096]; - while ((size=fread(buffer, 1, 4096, in))) - fwrite(buffer, 1, size, out); -} - -static int -phase5(FILE **in, FILE **references, int in_count, char *suffix, struct zip_info *zip_info) -{ - long long size; - int slices; - int zipnum,written_tiles; - struct tile_head *th,*th2; - create_tile_hash(); - - th=tile_head_root; - size=0; - slices=0; - fprintf(stderr, "Maximum slice size %Ld\n", slice_size); - while (th) { - if (size + th->total_size > slice_size) { - fprintf(stderr,"Slice %d is of size %Ld\n", slices, size); - size=0; - slices++; - } - size+=th->total_size; - th=th->next; - } - if (size) - fprintf(stderr,"Slice %d is of size %Ld\n", slices, size); - th=tile_head_root; - size=0; - slices=0; - while (th) { - th2=tile_head_root; - while (th2) { - th2->process=0; - th2=th2->next; - } - size=0; - while (th && size+th->total_size < slice_size) { - size+=th->total_size; - th->process=1; - th=th->next; - } - /* process_slice() modifies zip_info, but need to retain old info */ - zipnum=zip_info->zipnum; - written_tiles=process_slice(in, references, in_count, size, suffix, zip_info); - zip_info->zipnum=zipnum+written_tiles; - slices++; - } - return 0; -} - -static int -phase5_write_directory(struct zip_info *info) -{ - struct zip_eoc eoc = { - 0x06054b50, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0, - 0x0, - 0x0, - }; - - fseek(info->dir, 0, SEEK_SET); - cat(info->dir, info->res); - eoc.zipenum=info->zipnum; - eoc.zipecenn=info->zipnum; - eoc.zipecsz=info->dir_size; - eoc.zipeofst=info->offset; - fwrite(&eoc, sizeof(eoc), 1, info->res); - sig_alrm(0); -#ifndef _WIN32 - alarm(0); -#endif - return 0; -} - - - -static void -usage(FILE *f) -{ - /* DEVELOPPERS : don't forget to update the manpage if you modify theses options */ - fprintf(f,"\n"); - fprintf(f,"osm2navit - parse osm textfile and converts to NavIt binfile format\n\n"); - fprintf(f,"Usage :\n"); - fprintf(f,"bzcat planet.osm.bz2 | osm2navit mymap.bin\n"); - fprintf(f,"Available switches:\n"); - fprintf(f,"-h (--help) : this screen\n"); - fprintf(f,"-N (--nodes-only) : process only nodes\n"); - fprintf(f,"-W (--ways-only) : process only ways\n"); - fprintf(f,"-a (--attr-debug-level) : control which data is included in the debug attribute\n"); - fprintf(f,"-c (--dump-coordinates) : dump coordinates after phase 1\n"); -#ifdef HAVE_POSTGRESQL - fprintf(f,"-d (--db) : get osm data out of a postgresql database with osm simple scheme and given connect string\n"); -#endif - fprintf(f,"-e (--end) : end at specified phase\n"); - fprintf(f,"-k (--keep-tmpfiles) : do not delete tmp files after processing. useful to reuse them\n\n"); - fprintf(f,"-o (--coverage) : map every street to item coverage\n"); - fprintf(f,"-s (--start) : start at specified phase\n"); - fprintf(f,"-i (--input-file) : specify the input file name (OSM), overrules default stdin\n"); - fprintf(f,"-w (--dedupe-ways) : ensure no duplicate ways or nodes. useful when using several input files\n"); - fprintf(f,"-z (--compression-level) : set the compression level\n"); - exit(1); -} - -static void -process_binfile(FILE *in, FILE *out) -{ - struct item_bin *ib; - while ((ib=read_item(in))) { - fwrite(ib, (ib->len+1)*4, 1, out); - } -} - -static struct plugins *plugins; - -static void add_plugin(char *path) -{ - struct attr **attrs; - - if (! plugins) - plugins=plugins_new(); - attrs=(struct attr*[]){&(struct attr){attr_path,{path}},NULL}; - plugin_new(&(struct attr){attr_plugins,.u.plugins=plugins}, attrs); -} - -static struct item_bin_sink * -file_reader_new(FILE *in, int limit, int offset) -{ - struct item_bin_sink *ret; - if (!in) - return NULL; - ret=item_bin_sink_new(); - ret->priv_data[0]=in; - ret->priv_data[1]=(void *)(long)limit; - ret->priv_data[2]=(void *)(long)offset; - fseek(in, 0, SEEK_SET); - return ret; -} - -static int -file_reader_finish(struct item_bin_sink *sink) -{ - struct item_bin *ib=(struct item_bin *)buffer; - int ret =0; - FILE *in=sink->priv_data[0]; - int limit=(int)(long)sink->priv_data[1]; - int offset=(int)(long)sink->priv_data[2]; - for (;;) { - switch (item_bin_read(ib, in)) { - case 0: - item_bin_sink_destroy(sink); - return 0; - case 2: - if (offset > 0) { - offset--; - } else { - ret=item_bin_write_to_sink(ib, sink, NULL); - if (ret || (limit != -1 && !--limit)) { - item_bin_sink_destroy(sink); - return ret; - } - } - default: - continue; - } - } -} - -static int -file_writer_process(struct item_bin_sink_func *func, struct item_bin *ib, struct tile_data *tile_data) -{ - FILE *out=func->priv_data[0]; - item_bin_write(ib, out); - return 0; -} - -static struct item_bin_sink_func * -file_writer_new(FILE *out) -{ - struct item_bin_sink_func *file_writer; - if (!out) - return NULL; - file_writer=item_bin_sink_func_new(file_writer_process); - file_writer->priv_data[0]=out; - return file_writer; -} - -static int -file_writer_finish(struct item_bin_sink_func *file_writer) -{ - item_bin_sink_func_destroy(file_writer); - return 0; -} - - -static int -tile_collector_process(struct item_bin_sink_func *tile_collector, struct item_bin *ib, struct tile_data *tile_data) -{ - int *buffer,*buffer2; - int len=ib->len+1; - GHashTable *hash=tile_collector->priv_data[0]; - buffer=g_hash_table_lookup(hash, tile_data->buffer); - buffer2=g_malloc((len+(buffer ? buffer[0] : 1))*4); - if (buffer) { - memcpy(buffer2, buffer, buffer[0]*4); - } else - buffer2[0]=1; - memcpy(buffer2+buffer2[0], ib, len*4); - buffer2[0]+=len; - g_hash_table_insert(hash, g_strdup(tile_data->buffer), buffer2); - return 0; -} - -static struct item_bin_sink_func * -tile_collector_new(struct item_bin_sink *out) -{ - struct item_bin_sink_func *tile_collector; - tile_collector=item_bin_sink_func_new(tile_collector_process); - tile_collector->priv_data[0]=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - tile_collector->priv_data[1]=out; - return tile_collector; -} - - -static int distance_from_ll(struct coord *c, struct rect *bbox) -{ - int dist=0; - if (c->x == bbox->l.x) - return dist+c->y-bbox->l.y; - dist+=bbox->h.y-bbox->l.y; - if (c->y == bbox->h.y) - return dist+c->x-bbox->l.x; - dist+=bbox->h.x-bbox->l.x; - if (c->x == bbox->h.x) - return dist+bbox->h.y-c->y; - dist+=bbox->h.y-bbox->l.y; - if (c->y == bbox->l.y) - return dist+bbox->h.x-c->x; - return -1; -} - -static struct geom_poly_segment * -find_next(struct rect *bbox, GList *segments, struct coord *c, int exclude, struct coord *ci) -{ - int min=INT_MAX,search=distance_from_ll(c, bbox)+(exclude?1:0); - GList *curr; - int i; - struct geom_poly_segment *ret=NULL; - int dbgl=1; - - for (i = 0 ; i < 2 ; i++) { - curr=segments; - dbg(dbgl,"search distance %d\n",search); - while (curr) { - struct geom_poly_segment *seg=curr->data; - int dist=distance_from_ll(seg->first, bbox); - dbg(dbgl,"0x%x 0x%x dist %d\n",seg->first->x,seg->first->y,dist); - if (dist != -1 && seg->first != seg->last && dist < min && (dist >= search)) { - min=dist; - ci[0]=*seg->first; - ci[1]=*seg->last; - ret=seg; - } - curr=g_list_next(curr); - } - if (ret || !search) - break; - search=0; - } - return ret; -} - -static void -close_polygon(struct item_bin *ib, struct coord *from, struct coord *to, int dir, struct rect *bbox, int *edges) -{ - int i,e,dist,fromdist,todist; - int full=(bbox->h.x-bbox->l.x+bbox->h.y-bbox->l.y)*2; - int corners=0,first_corner=0; - struct coord c; - if (dir > 0) { - fromdist=distance_from_ll(from, bbox); - todist=distance_from_ll(to, bbox); - } else { - fromdist=distance_from_ll(to, bbox); - todist=distance_from_ll(from, bbox); - } -#if 0 - fprintf(stderr,"close_polygon fromdist %d todist %d full %d dir %d\n", fromdist, todist, full, dir); -#endif - if (fromdist > todist) - todist+=full; -#if 0 - fprintf(stderr,"close_polygon corrected fromdist %d todist %d full %d dir %d\n", fromdist, todist, full, dir); -#endif - for (i = 0 ; i < 8 ; i++) { - if (dir > 0) - e=i; - else - e=7-i; - switch (e%4) { - case 0: - c=bbox->l; - break; - case 1: - c.x=bbox->l.x; - c.y=bbox->h.y; - break; - case 2: - c=bbox->h; - break; - case 3: - c.x=bbox->h.x; - c.y=bbox->l.y; - break; - } - dist=distance_from_ll(&c, bbox); - if (e & 4) - dist+=full; -#if 0 - fprintf(stderr,"dist %d %d\n",e,dist); -#endif - if (dist > fromdist && dist < todist) { - item_bin_add_coord(ib, &c, 1); -#if 0 - fprintf(stderr,"add\n"); -#endif - } - if (dist >= fromdist && dist <= todist) { - if (!corners) - first_corner=e; - corners++; - } - } - while (corners >= 2) { - *edges |= 1<<(first_corner%4); - first_corner++; - corners--; - } -} - -struct coastline_tile_data { - struct item_bin_sink_func *sink; - GHashTable *tile_edges; - int level; -}; - -static GList * -tile_data_to_segments(int *tile_data) -{ - int *end=tile_data+tile_data[0]; - int *curr=tile_data+1; - GList *segments=NULL; - int count=0; - - while (curr < end) { - struct item_bin *ib=(struct item_bin *)curr; - segments=g_list_prepend(segments,item_bin_to_poly_segment(ib, geom_poly_segment_type_way_right_side)); - curr+=ib->len+1; - count++; - } -#if 0 - fprintf(stderr,"%d segments\n",count); -#endif - return segments; -} - -static void -tile_collector_process_tile(char *tile, int *tile_data, struct coastline_tile_data *data) -{ - int poly_start_valid,tile_start_valid,exclude,search=0,workload=0; - struct rect bbox; - struct coord c,cn[2],end,poly_start,tile_start; - struct geom_poly_segment *first; - struct item_bin *ib=(struct item_bin *)buffer; - struct item_bin_sink *out=data->sink->priv_data[1]; - int dbgl=1; - int edges=0,flags; - GList *sorted_segments,*curr; -#if 0 - if (strncmp(tile,"bcdbdcabddddba",7)) - return; -#endif -#if 0 - if (strncmp(tile,"bcdbdcaaaaddba",14)) - return; -#endif -#if 0 - fprintf(stderr,"tile %s of size %d\n", tile, *tile_data); -#endif - tile_bbox(tile, &bbox, 0); - sorted_segments=geom_poly_segments_sort(tile_data_to_segments(tile_data), geom_poly_segment_type_way_right_side); -#if 0 -{ - GList *sort_segments=sorted_segments; - int count=0; - while (sort_segments) { - struct geom_poly_segment *seg=sort_segments->data; - struct item_bin *ib=(struct item_bin *)buffer; - char *text=g_strdup_printf("segment %d type %d %p %s area %Ld",count++,seg->type,sort_segments,coord_is_equal(*seg->first, *seg->last) ? "closed":"open",geom_poly_area(seg->first,seg->last-seg->first+1)); - item_bin_init(ib, type_rg_segment); - item_bin_add_coord(ib, seg->first, seg->last-seg->first+1); - item_bin_add_attr_string(ib, attr_debug, text); - // fprintf(stderr,"%s\n",text); - g_free(text); - // item_bin_dump(ib, stderr); - item_bin_write_to_sink(ib, out, NULL); - sort_segments=g_list_next(sort_segments); - } -} -#endif - flags=0; - curr=sorted_segments; - while (curr) { - struct geom_poly_segment *seg=curr->data; - switch (seg->type) { - case geom_poly_segment_type_way_inner: - flags|=1; - break; - case geom_poly_segment_type_way_outer: - flags|=2; - break; - default: - flags|=4; - break; - } - curr=g_list_next(curr); - } - if (flags == 1) { - item_bin_init(ib, type_poly_water_tiled); - item_bin_bbox(ib, &bbox); - item_bin_write_to_sink(ib, out, NULL); - g_hash_table_insert(data->tile_edges, g_strdup(tile), (void *)15); - return; - } -#if 1 - end=bbox.l; - tile_start_valid=0; - poly_start_valid=0; - exclude=0; - poly_start.x=0; - poly_start.y=0; - tile_start.x=0; - tile_start.y=0; - for (;;) { - search++; - // item_bin_write_debug_point_to_sink(out, &end, "Search %d",search); - dbg(dbgl,"searching next polygon from 0x%x 0x%x\n",end.x,end.y); - first=find_next(&bbox, sorted_segments, &end, exclude, cn); - exclude=1; - if (!first) - break; - if (!tile_start_valid) { - tile_start=cn[0]; - tile_start_valid=1; - } else { - if (cn[0].x == tile_start.x && cn[0].y == tile_start.y) { - dbg(dbgl,"end of tile reached\n"); - break; - } - } - if (first->type == geom_poly_segment_type_none) { - end=cn[0]; - continue; - } - poly_start_valid=0; - dbg(dbgl,"start of polygon 0x%x 0x%x\n",cn[0].x,cn[0].y); - for (;;) { - if (!poly_start_valid) { - poly_start=cn[0]; - poly_start_valid=1; - item_bin_init(ib,type_poly_water_tiled); - } else { - close_polygon(ib, &end, &cn[0], 1, &bbox, &edges); - if (cn[0].x == poly_start.x && cn[0].y == poly_start.y) { - dbg(dbgl,"poly end reached\n"); - item_bin_write_to_sink(ib, out, NULL); - end=cn[0]; - break; - } - } - if (first->type == geom_poly_segment_type_none) - break; - item_bin_add_coord(ib, first->first, first->last-first->first+1); - first->type=geom_poly_segment_type_none; - end=cn[1]; - if (distance_from_ll(&end, &bbox) == -1) { - dbg(dbgl,"incomplete\n"); - break; - } - first=find_next(&bbox, sorted_segments, &end, 1, cn); - dbg(dbgl,"next segment of polygon 0x%x 0x%x\n",cn[0].x,cn[0].y); - } - if (search > 55) - break; - } -#endif - -#if 0 - { - int *end=tile_data+tile_data[0]; - int *curr=tile_data+1; - while (curr < end) { - struct item_bin *ib=(struct item_bin *)curr; - // item_bin_dump(ib); - ib->type=type_rg_segment; - item_bin_write_to_sink(ib, out, NULL); - curr+=ib->len+1; -#if 0 - { - struct coord *c[2]; - int i; - char *s; - c[0]=(struct coord *)(ib+1); - c[1]=c[0]+ib->clen/2-1; - for (i = 0 ; i < 2 ; i++) { - s=coord_to_str(c[i]); - item_bin_write_debug_point_to_sink(out, c[i], "%s",s); - g_free(s); - } - - } -#endif - } - } -#endif - g_hash_table_insert(data->tile_edges, g_strdup(tile), (void *)edges); -#if 0 - item_bin_init(ib, type_border_country); - item_bin_bbox(ib, &bbox); - item_bin_add_attr_string(ib, attr_debug, tile); - item_bin_write_to_sink(ib, out, NULL); -#endif -#if 0 - c.x=(bbox.l.x+bbox.h.x)/2; - c.y=(bbox.l.y+bbox.h.y)/2; - item_bin_write_debug_point_to_sink(out, &c, "%s %d",tile,edges); -#endif -} - -static void -ocean_tile(GHashTable *hash, char *tile, char c, struct item_bin_sink *out) -{ - int len=strlen(tile); - char tile2[len+1]; - struct rect bbox; - struct item_bin *ib=(struct item_bin *)buffer; - struct coord co; - - strcpy(tile2, tile); - tile2[len-1]=c; - //fprintf(stderr,"Testing %s\n",tile2); - if (g_hash_table_lookup_extended(hash, tile2, NULL, NULL)) - return; - //fprintf(stderr,"%s ok\n",tile2); - tile_bbox(tile2, &bbox, 0); - item_bin_init(ib,type_poly_water_tiled); - item_bin_bbox(ib, &bbox); - item_bin_write_to_sink(ib, out, NULL); - g_hash_table_insert(hash, g_strdup(tile2), (void *)15); -#if 0 - item_bin_init(ib, type_border_country); - item_bin_bbox(ib, &bbox); - item_bin_add_attr_string(ib, attr_debug, tile2); - item_bin_write_to_sink(ib, out, NULL); -#endif - co.x=(bbox.l.x+bbox.h.x)/2; - co.y=(bbox.l.y+bbox.h.y)/2; - //item_bin_write_debug_point_to_sink(out, &co, "%s 15",tile2); - -} - -/* ba */ -/* dc */ - -static void -tile_collector_add_siblings(char *tile, void *edgesp, struct coastline_tile_data *data) -{ - int len=strlen(tile); - char t=tile[len-1]; - struct item_bin_sink *out=data->sink->priv_data[1]; - int edges=(int)edgesp; - int debug=0; - - if (len != data->level) - return; -#if 0 - if (!strncmp(tile,"bcacccaadbdcd",10)) - debug=1; -#endif - if (debug) - fprintf(stderr,"%s (%c) has %d edges active\n",tile,t,edges); - if (t == 'a' && (edges & 1)) - ocean_tile(data->tile_edges, tile, 'b', out); - if (t == 'a' && (edges & 8)) - ocean_tile(data->tile_edges, tile, 'c', out); - if (t == 'b' && (edges & 4)) - ocean_tile(data->tile_edges, tile, 'a', out); - if (t == 'b' && (edges & 8)) - ocean_tile(data->tile_edges, tile, 'd', out); - if (t == 'c' && (edges & 1)) - ocean_tile(data->tile_edges, tile, 'd', out); - if (t == 'c' && (edges & 2)) - ocean_tile(data->tile_edges, tile, 'a', out); - if (t == 'd' && (edges & 4)) - ocean_tile(data->tile_edges, tile, 'c', out); - if (t == 'd' && (edges & 2)) - ocean_tile(data->tile_edges, tile, 'b', out); -} - -static int -tile_sibling_edges(GHashTable *hash, char *tile, char c) -{ - int len=strlen(tile); - int ret; - char tile2[len+1]; - void *data; - strcpy(tile2, tile); - tile2[len-1]=c; - if (!g_hash_table_lookup_extended(hash, tile2, NULL, &data)) - ret=15; - else - ret=(int)data; - //fprintf(stderr,"checking '%s' with %d edges active\n",tile2,ret); - - return ret; -} - -static void -ocean_tile2(struct rect *r, int dx, int dy, int wf, int hf, struct item_bin_sink *out) -{ - struct item_bin *ib=(struct item_bin *)buffer; - int w=r->h.x-r->l.x; - int h=r->h.y-r->l.y; - char tile2[32]; - struct rect bbox; - struct coord co; - bbox.l.x=r->l.x+dx*w; - bbox.l.y=r->l.y+dy*h; - bbox.h.x=bbox.l.x+w*wf; - bbox.h.y=bbox.l.y+h*hf; - //fprintf(stderr,"0x%x,0x%x-0x%x,0x%x -> 0x%x,0x%x-0x%x,0x%x\n",r->l.x,r->l.y,r->h.x,r->h.y,bbox.l.x,bbox.l.y,bbox.h.x,bbox.h.y); - item_bin_init(ib,type_poly_water_tiled); - item_bin_bbox(ib, &bbox); - item_bin_write_to_sink(ib, out, NULL); -#if 0 - item_bin_init(ib, type_border_country); - item_bin_bbox(ib, &bbox); - item_bin_add_attr_string(ib, attr_debug, tile2); - item_bin_write_to_sink(ib, out, NULL); -#endif - tile(&bbox, NULL, tile2, 32, 0, NULL); - co.x=(bbox.l.x+bbox.h.x)/2; - co.y=(bbox.l.y+bbox.h.y)/2; - //item_bin_write_debug_point_to_sink(out, &co, "%s 15",tile2); -} - -static void -tile_collector_add_siblings2(char *tile, void *edgesp, struct coastline_tile_data *data) -{ - int len=strlen(tile); - char tile2[len+1]; - char t=tile[len-1]; - strcpy(tile2, tile); - tile2[len-1]='\0'; - struct item_bin_sink *out=data->sink->priv_data[1]; - struct rect bbox; - int edges=(int)edgesp; - int pedges=0; - int debug=0; -#if 0 - if (!strncmp(tile,"bcacccaadbdcd",10)) - debug=1; -#endif - if (debug) - fprintf(stderr,"len of %s %d vs %d\n",tile,len,data->level); - if (len != data->level) - return; - - - if (debug) - fprintf(stderr,"checking siblings of '%s' with %d edges active\n",tile,edges); - if (t == 'b' && (edges & 1) && (tile_sibling_edges(data->tile_edges, tile, 'd') & 1)) - pedges|=1; - if (t == 'd' && (edges & 2) && (tile_sibling_edges(data->tile_edges, tile, 'b') & 1)) - pedges|=1; - if (t == 'a' && (edges & 2) && (tile_sibling_edges(data->tile_edges, tile, 'b') & 2)) - pedges|=2; - if (t == 'b' && (edges & 2) && (tile_sibling_edges(data->tile_edges, tile, 'a') & 2)) - pedges|=2; - if (t == 'a' && (edges & 4) && (tile_sibling_edges(data->tile_edges, tile, 'c') & 4)) - pedges|=4; - if (t == 'c' && (edges & 4) && (tile_sibling_edges(data->tile_edges, tile, 'a') & 4)) - pedges|=4; - if (t == 'd' && (edges & 8) && (tile_sibling_edges(data->tile_edges, tile, 'c') & 8)) - pedges|=8; - if (t == 'c' && (edges & 8) && (tile_sibling_edges(data->tile_edges, tile, 'd') & 8)) - pedges|=8; - if (debug) - fprintf(stderr,"result '%s' %d old %d\n",tile2,pedges,(int)g_hash_table_lookup(data->tile_edges, tile2)); - g_hash_table_insert(data->tile_edges, g_strdup(tile2), (void *)((int)g_hash_table_lookup(data->tile_edges, tile2)|pedges)); -} - -static int -tile_collector_finish(struct item_bin_sink_func *tile_collector) -{ - struct coastline_tile_data data; - int i; - data.sink=tile_collector; - data.tile_edges=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); - GHashTable *hash=tile_collector->priv_data[0]; - fprintf(stderr,"tile_collector_finish\n"); - g_hash_table_foreach(hash, tile_collector_process_tile, &data); - fprintf(stderr,"tile_collector_finish foreach done\n"); - g_hash_table_destroy(hash); - fprintf(stderr,"tile_collector_finish destroy done\n"); - for (i = 14 ; i > 0 ; i--) { - fprintf(stderr,"Level=%d\n",i); - data.level=i; - g_hash_table_foreach(data.tile_edges, tile_collector_add_siblings, &data); - fprintf(stderr,"*"); - g_hash_table_foreach(data.tile_edges, tile_collector_add_siblings, &data); - fprintf(stderr,"*"); - g_hash_table_foreach(data.tile_edges, tile_collector_add_siblings, &data); - fprintf(stderr,"*"); - g_hash_table_foreach(data.tile_edges, tile_collector_add_siblings, &data); - fprintf(stderr,"*"); - g_hash_table_foreach(data.tile_edges, tile_collector_add_siblings2, &data); - fprintf(stderr,"*\n"); - g_hash_table_foreach(data.tile_edges, tile_collector_add_siblings2, &data); - fprintf(stderr,"*\n"); - g_hash_table_foreach(data.tile_edges, tile_collector_add_siblings2, &data); - fprintf(stderr,"*\n"); - g_hash_table_foreach(data.tile_edges, tile_collector_add_siblings2, &data); - fprintf(stderr,"*\n"); - } -#if 0 - data.level=13; - g_hash_table_foreach(data.tile_edges, tile_collector_add_siblings, &data); - g_hash_table_foreach(data.tile_edges, tile_collector_add_siblings, &data); - g_hash_table_foreach(data.tile_edges, tile_collector_add_siblings2, &data); - data.level=12; - g_hash_table_foreach(data.tile_edges, tile_collector_add_siblings, &data); - g_hash_table_foreach(data.tile_edges, tile_collector_add_siblings, &data); -#endif - item_bin_sink_func_destroy(tile_collector); - fprintf(stderr,"tile_collector_finish done\n"); - return 0; -} - - -static int -coastline_processor_process(struct item_bin_sink_func *func, struct item_bin *ib, struct tile_data *tile_data) -{ - int i; - struct coord *c=(struct coord *)(ib+1); -#if 0 - for (i = 0 ; i < 19 ; i++) { - c[i]=c[i+420]; - } - ib->clen=(i-1)*2; -#endif - item_bin_write_clipped(ib, func->priv_data[0], func->priv_data[1]); - return 0; -} - -static struct item_bin_sink_func * -coastline_processor_new(struct item_bin_sink *out) -{ - struct item_bin_sink_func *coastline_processor=item_bin_sink_func_new(coastline_processor_process); - struct item_bin_sink *tiles=item_bin_sink_new(); - struct item_bin_sink_func *tile_collector=tile_collector_new(out); - struct tile_parameter *param=g_new0(struct tile_parameter, 1); - - fprintf(stderr,"new:out=%p\n",out); - param->min=14; - param->max=14; - param->overlap=0; - - item_bin_sink_add_func(tiles, tile_collector); - coastline_processor->priv_data[0]=param; - coastline_processor->priv_data[1]=tiles; - coastline_processor->priv_data[2]=tile_collector; - return coastline_processor; -} - -static void -coastline_processor_finish(struct item_bin_sink_func *coastline_processor) -{ - struct tile_parameter *param=coastline_processor->priv_data[0]; - struct item_bin_sink *tiles=coastline_processor->priv_data[1]; - struct item_bin_sink_func *tile_collector=coastline_processor->priv_data[2]; - g_free(param); - tile_collector_finish(tile_collector); - item_bin_sink_destroy(tiles); - item_bin_sink_func_destroy(coastline_processor); -} - -static void -process_coastlines(FILE *in, FILE *out) -{ - struct item_bin_sink *reader=file_reader_new(in,1000000,0); - struct item_bin_sink_func *file_writer=file_writer_new(out); - struct item_bin_sink *result=item_bin_sink_new(); - struct item_bin_sink_func *coastline_processor=coastline_processor_new(result); - item_bin_sink_add_func(reader, coastline_processor); - item_bin_sink_add_func(result, file_writer); - file_reader_finish(reader); - coastline_processor_finish(coastline_processor); - file_writer_finish(file_writer); - item_bin_sink_destroy(result); -} - -static FILE * -tempfile(char *suffix, char *name, int mode) -{ - char buffer[4096]; - sprintf(buffer,"%s_%s.tmp",name, suffix); - switch (mode) { - case 0: - return fopen(buffer, "rb"); - case 1: - return fopen(buffer, "wb+"); - case 2: - return fopen(buffer, "ab"); - default: - return NULL; - } -} - -static void -tempfile_unlink(char *suffix, char *name) -{ - char buffer[4096]; - sprintf(buffer,"%s_%s.tmp",name, suffix); - unlink(buffer); -} - -static void -tempfile_rename(char *suffix, char *from, char *to) -{ - char buffer_from[4096],buffer_to[4096]; - sprintf(buffer_from,"%s_%s.tmp",from,suffix); - sprintf(buffer_to,"%s_%s.tmp",to,suffix); - assert(rename(buffer_from, buffer_to) == 0); - -} - -int main(int argc, char **argv) -{ - FILE *ways=NULL,*ways_split=NULL,*ways_split_index=NULL,*nodes=NULL,*turn_restrictions=NULL,*graph=NULL,*coastline=NULL,*tilesdir,*coords,*relations=NULL; - FILE *files[10]; - FILE *references[10]; - - char *map=g_strdup(attrmap); - int zipnum,c,start=1,end=99,dump_coordinates=0; - int keep_tmpfiles=0; - int process_nodes=1, process_ways=1, process_relations=1; -#ifdef HAVE_ZLIB - int compression_level=9; -#else - int compression_level=0; -#endif - int output=0; - int input=0; - int f; - char *result; -#ifdef HAVE_POSTGRESQL - char *dbstr=NULL; -#endif - FILE* input_file = stdin; - struct attr **attrs; - struct map *map_handle=NULL; -#if 0 - char *suffixes[]={"m0l0", "m0l1","m0l2","m0l3","m0l4","m0l5","m0l6"}; -#else - char *suffixes[]={""}; -#endif - int suffix_count=sizeof(suffixes)/sizeof(char *); - int i; - main_init(argv[0]); - struct zip_info zip_info; - - while (1) { -#if 0 - int this_option_optind = optind ? optind : 1; -#endif - int option_index = 0; - static struct option long_options[] = { - {"attr-debug-level", 1, 0, 'a'}, - {"binfile", 0, 0, 'b'}, - {"compression-level", 1, 0, 'z'}, - {"coverage", 0, 0, 'o'}, -#ifdef HAVE_POSTGRESQL - {"db", 1, 0, 'd'}, -#endif - {"dedupe-ways", 0, 0, 'w'}, - {"dump", 0, 0, 'D'}, - {"dump-coordinates", 0, 0, 'c'}, - {"end", 1, 0, 'e'}, - {"help", 0, 0, 'h'}, - {"keep-tmpfiles", 0, 0, 'k'}, - {"nodes-only", 0, 0, 'N'}, - {"map", 1, 0, 'm'}, - {"plugin", 1, 0, 'p'}, - {"start", 1, 0, 's'}, - {"input-file", 1, 0, 'i'}, - {"ignore-unknown", 0, 0, 'n'}, - {"ways-only", 0, 0, 'W'}, - {"slice-size", 1, 0, 'S'}, - {0, 0, 0, 0} - }; - c = getopt_long (argc, argv, "DNWS:a:bc" -#ifdef HAVE_POSTGRESQL - "d:" -#endif - "e:hi:knm:p:s:wz:", long_options, &option_index); - if (c == -1) - break; - switch (c) { - case 'D': - output=1; - break; - case 'N': - process_ways=0; - break; - case 'R': - process_relations=0; - break; - case 'S': - slice_size=atoll(optarg); - break; - case 'W': - process_nodes=0; - break; - case 'a': - attr_debug_level=atoi(optarg); - break; - case 'b': - input=1; - break; - case 'c': - dump_coordinates=1; - break; -#ifdef HAVE_POSTGRESQL - case 'd': - dbstr=optarg; - break; -#endif - case 'e': - end=atoi(optarg); - break; - case 'h': - usage(stdout); - break; - case 'm': - attrs=(struct attr*[]){ - &(struct attr){attr_type,{"textfile"}}, - &(struct attr){attr_data,{optarg}}, - NULL}; - add_plugin("$NAVIT_LIBDIR/*/${NAVIT_LIBPREFIX}libmap_textfile.so"); - map_handle=map_new(NULL, attrs); - break; - case 'n': - fprintf(stderr,"I will IGNORE unknown types\n"); - ignore_unkown=1; - break; - case 'k': - fprintf(stderr,"I will KEEP tmp files\n"); - keep_tmpfiles=1; - break; - case 'o': - coverage=1; - break; - case 'p': - add_plugin(optarg); - break; - case 's': - start=atoi(optarg); - break; - case 'w': - dedupe_ways_hash=g_hash_table_new(NULL, NULL); - break; - case 'i': - input_file = fopen( optarg, "r" ); - if ( input_file == NULL ) - { - fprintf( stderr, "\nInput file (%s) not found\n", optarg ); - exit( -1 ); - } - break; -#ifdef HAVE_ZLIB - case 'z': - compression_level=atoi(optarg); - break; -#endif - case '?': - usage(stderr); - break; - default: - fprintf(stderr,"c=%d\n", c); - } - - } - if (optind != argc-(output == 1 ? 0:1)) - usage(stderr); - if (plugins) - plugins_init(plugins); - result=argv[optind]; - build_attrmap(map); - build_countrytable(); - - - if (input == 0) { - if (start == 1) { - unlink("coords.tmp"); - if (process_ways) - ways=tempfile(suffix,"ways",1); - if (process_nodes) - nodes=tempfile(suffix,"nodes",1); - if (process_ways && process_nodes) - turn_restrictions=tempfile(suffix,"turn_restrictions",1); - phase=1; - fprintf(stderr,"PROGRESS: Phase 1: collecting data\n"); -#ifdef HAVE_POSTGRESQL - if (dbstr) - phase1_db(dbstr,ways,nodes); - else -#endif - if (map_handle) { - phase1_map(map_handle,ways,nodes); - map_destroy(map_handle); - } - else - phase1(input_file,ways,nodes,turn_restrictions); - if (slices) { - fprintf(stderr,"%d slices\n",slices); - flush_nodes(1); - for (i = slices-2 ; i>=0 ; i--) { - fprintf(stderr, "slice %d of %d\n",slices-i-1,slices-1); - load_buffer("coords.tmp",&node_buffer, i*slice_size, slice_size); - resolve_ways(ways, NULL); - save_buffer("coords.tmp",&node_buffer, i*slice_size); - } - } else - save_buffer("coords.tmp",&node_buffer, 0); - if (ways) - fclose(ways); - if (nodes) - fclose(nodes); - if (turn_restrictions) - fclose(turn_restrictions); - } - if (!slices) { - if (end == 1 || dump_coordinates) - flush_nodes(1); - else - slices++; - } - if (end == 1) - exit(0); - if (start == 2) { - load_buffer("coords.tmp",&node_buffer,0, slice_size); - } - if (start <= 2) { - if (process_ways) { - ways=tempfile(suffix,"ways",0); - phase=2; - fprintf(stderr,"PROGRESS: Phase 2: finding intersections\n"); - for (i = 0 ; i < slices ; i++) { - int final=(i >= slices-1); - ways_split=tempfile(suffix,"ways_split",1); - ways_split_index=final ? tempfile(suffix,"ways_split_index",1) : NULL; - graph=tempfile(suffix,"graph",1); - coastline=tempfile(suffix,"coastline",1); - if (i) - load_buffer("coords.tmp",&node_buffer, i*slice_size, slice_size); - phase2(ways,ways_split,ways_split_index,graph,coastline,final); - fclose(ways_split); - if (ways_split_index) - fclose(ways_split_index); - fclose(ways); - fclose(graph); - fclose(coastline); - if (! final) { - tempfile_rename(suffix,"ways_split","ways_to_resolve"); - ways=tempfile(suffix,"ways_to_resolve",0); - } - } - if(!keep_tmpfiles) - tempfile_unlink(suffix,"ways"); - tempfile_unlink(suffix,"ways_to_resolve"); - } else - fprintf(stderr,"PROGRESS: Skipping Phase 2\n"); - } - free(node_buffer.base); - node_buffer.base=NULL; - node_buffer.malloced=0; - node_buffer.size=0; - if (end == 2) - exit(0); - } else { - ways_split=tempfile(suffix,"ways_split",0); - process_binfile(stdin, ways_split); - fclose(ways_split); - } -#if 1 - coastline=tempfile(suffix,"coastline",0); - ways_split=tempfile(suffix,"ways_split",2); - fprintf(stderr,"coastline=%p\n",coastline); - process_coastlines(coastline, ways_split); - fclose(ways_split); - fclose(coastline); -#endif - if (start <= 3) { - fprintf(stderr,"PROGRESS: Phase 3: sorting countries, generating turn restrictions\n"); - sort_countries(keep_tmpfiles); - if (process_relations) { - turn_restrictions=tempfile(suffix,"turn_restrictions",0); - relations=tempfile(suffix,"relations",1); - coords=fopen("coords.tmp","rb"); - ways_split=tempfile(suffix,"ways_split",0); - ways_split_index=tempfile(suffix,"ways_split_index",0); - process_turn_restrictions(turn_restrictions,coords,ways_split,ways_split_index,relations); -#if 0 - process_countries(ways_split,ways_split_index); -#endif - fclose(ways_split_index); - fclose(ways_split); - fclose(coords); - fclose(relations); - fclose(turn_restrictions); - if(!keep_tmpfiles) - tempfile_unlink(suffix,"turn_restrictions"); - } - if(!keep_tmpfiles) - tempfile_unlink(suffix,"ways_split_index"); - } - if (end == 3) - exit(0); - if (output == 1) { - fprintf(stderr,"PROGRESS: Phase 4: dumping\n"); - if (process_nodes) { - nodes=tempfile(suffix,"nodes",0); - if (nodes) { - dump(nodes); - fclose(nodes); - } - } - if (process_ways) { - ways_split=tempfile(suffix,"ways_split",0); - if (ways_split) { - dump(ways_split); - fclose(ways_split); - } - } - if (process_relations) { - relations=tempfile(suffix,"relations",0); - fprintf(stderr,"Relations=%p\n",relations); - if (relations) { - dump(relations); - fclose(relations); - } - } - exit(0); - } - for (i = 0 ; i < suffix_count ; i++) { - suffix=suffixes[i]; - if (start <= 4) { - phase=3; - if (i == 0) { - memset(&zip_info, 0, sizeof(zip_info)); - } - zipnum=zip_info.zipnum; - fprintf(stderr,"PROGRESS: Phase 4: generating tiles %s\n",suffix); - files[0]=NULL; - files[1]=NULL; - files[2]=NULL; - if (process_relations) - files[0]=tempfile(suffix,"relations",0); - if (process_ways) - files[1]=tempfile(suffix,"ways_split",0); - if (process_nodes) - files[2]=tempfile(suffix,"nodes",0); - tilesdir=tempfile(suffix,"tilesdir",1); - phase4(files,3,suffix,tilesdir,&zip_info); - fclose(tilesdir); - if (files[2]) - fclose(files[2]); - if (files[1]) - fclose(files[1]); - if (files[0]) - fclose(files[0]); - zip_info.zipnum=zipnum; - } - if (end == 4) - exit(0); - if (start <= 5) { - phase=4; - fprintf(stderr,"PROGRESS: Phase 5: assembling map %s\n",suffix); - files[0]=NULL; - files[1]=NULL; - files[2]=NULL; - references[0]=NULL; - references[1]=NULL; - references[2]=NULL; - if (process_relations) - files[0]=tempfile(suffix,"relations",0); - if (process_ways) { - files[1]=tempfile(suffix,"ways_split",0); - references[1]=tempfile(suffix,"ways_split_ref",1); - printf("References=%p\n",references[1]); - } - if (process_nodes) - files[2]=tempfile(suffix,"nodes",0); - if (i == 0) { - zip_info.dir_size=0; - zip_info.offset=0; - zip_info.maxnamelen=14+strlen(suffixes[0]); - zip_info.compression_level=compression_level; - zip_info.zipnum=0; - zip_info.dir=tempfile("zipdir","",1); - zip_info.index=tempfile("index","",1); - zip_info.res=fopen(result,"wb+"); - index_init(&zip_info, 1); - } - fprintf(stderr,"Slice %d\n",i); - - phase5(files,references,3,suffix,&zip_info); - for (f = 0 ; f < 3 ; f++) { - if (files[f]) - fclose(files[f]); - if (references[f]) - fclose(references[f]); - } - if(!keep_tmpfiles) { - tempfile_unlink(suffix,"relations"); - tempfile_unlink(suffix,"nodes"); - tempfile_unlink(suffix,"ways_split"); - tempfile_unlink(suffix,"ways_split_ref"); - tempfile_unlink(suffix,"coastline"); - tempfile_unlink(suffix,"turn_restrictions"); - tempfile_unlink(suffix,"graph"); - tempfile_unlink(suffix,"tilesdir"); - tempfile_unlink("zipdir",""); - unlink("coords.tmp"); - } - if (i == suffix_count-1) { - zipnum=zip_info.zipnum; - write_countrydir(&zip_info); - zip_info.zipnum=zipnum; - write_aux_tiles(&zip_info); - write_index(&zip_info); - phase5_write_directory(&zip_info); - fclose(zip_info.index); - fclose(zip_info.dir); - fclose(zip_info.res); - if (!keep_tmpfiles) { - remove_countryfiles(); - tempfile_unlink("index",""); - } - } - } - } - return 0; -}