summaryrefslogtreecommitdiff
path: root/navit/maptool
diff options
context:
space:
mode:
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2011-07-10 19:29:52 +0000
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2011-07-10 19:29:52 +0000
commitc97b10d60f37adc95fa87ea02bff04743a0a7ac1 (patch)
treec7248889ca13e885adcf575dfef4689f6db9e84c /navit/maptool
parentd328fba164612e9414dcc9bf4c4e43777d485ecf (diff)
downloadnavit-c97b10d60f37adc95fa87ea02bff04743a0a7ac1.tar.gz
Add:maptool:Experimental support for boundary relations
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@4618 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'navit/maptool')
-rw-r--r--navit/maptool/boundaries.c54
-rw-r--r--navit/maptool/maptool.c20
-rw-r--r--navit/maptool/maptool.h22
-rw-r--r--navit/maptool/osm.c147
4 files changed, 190 insertions, 53 deletions
diff --git a/navit/maptool/boundaries.c b/navit/maptool/boundaries.c
index e83fb4ea9..54f1b0e94 100644
--- a/navit/maptool/boundaries.c
+++ b/navit/maptool/boundaries.c
@@ -20,13 +20,6 @@
#include <string.h>
#include "maptool.h"
-struct boundary {
- struct item_bin *ib;
- GList *segments,*sorted_segments;
- GList *children;
- struct rect r;
-};
-
struct boundary_member {
long long wayid;
enum geom_poly_segment_type role;
@@ -51,16 +44,23 @@ boundary_member_equal(gconstpointer a, gconstpointer b)
GHashTable *member_hash;
static char *
-osm_tag_name(struct item_bin *ib)
+osm_tag_value(struct item_bin *ib, char *key)
{
char *tag=NULL;
+ int len=strlen(key);
while ((tag=item_bin_get_attr(ib, attr_osm_tag, tag))) {
- if (!strncmp(tag,"name=",5))
- return tag+5;
+ if (!strncmp(tag,key,len) && tag[len] == '=')
+ return tag+len+1;
}
return NULL;
}
+static char *
+osm_tag_name(struct item_bin *ib)
+{
+ return osm_tag_value(ib, "name");
+}
+
static GList *
build_boundaries(FILE *boundaries)
{
@@ -70,6 +70,17 @@ build_boundaries(FILE *boundaries)
while ((ib=read_item(boundaries))) {
char *member=NULL;
struct boundary *boundary=g_new0(struct boundary, 1);
+ char *admin_level=osm_tag_value(ib, "admin_level");
+ char *iso=osm_tag_value(ib, "ISO3166-1");
+ if (admin_level && !strcmp(admin_level, "2")) {
+ if (iso) {
+ struct country_table *country=country_from_iso2(iso);
+ if (!country)
+ osm_warning("relation",item_bin_get_relationid(ib),0,"Country Boundary contains unknown ISO3166-1 value '%s'\n",iso);
+ boundary->country=country;
+ } else
+ osm_warning("relation",item_bin_get_relationid(ib),0,"Country Boundary doesn't contain an ISO3166-1 tag\n");
+ }
while ((member=item_bin_get_attr(ib, attr_osm_member, member))) {
long long wayid;
int read=0;
@@ -98,19 +109,20 @@ build_boundaries(FILE *boundaries)
return boundaries_list;
}
-static void
-find_matches(GList *l, struct coord *c)
+GList *
+boundary_find_matches(GList *l, struct coord *c)
{
+ GList *ret=NULL;
while (l) {
struct boundary *boundary=l->data;
if (bbox_contains_coord(&boundary->r, c)) {
- struct item_bin *ib=boundary->ib;
if (geom_poly_segments_point_inside(boundary->sorted_segments,c))
- printf("%s,",osm_tag_name(ib));
- find_matches(boundary->children, c);
+ ret=g_list_prepend(ret, boundary);
+ ret=g_list_concat(ret,boundary_find_matches(boundary->children, c));
}
l=g_list_next(l);
}
+ return ret;
}
static void
@@ -123,7 +135,7 @@ test(GList *boundaries_list)
struct coord *c=(struct coord *)(ib+1);
char *name=item_bin_get_attr(ib, attr_town_name, NULL);
printf("%s:",name);
- find_matches(boundaries_list, c);
+ boundary_find_matches(boundaries_list, c);
printf("\n");
}
fclose(f);
@@ -158,7 +170,7 @@ boundary_bbox_compare(gconstpointer a, gconstpointer b)
return 0;
}
-int
+GList *
process_boundaries(FILE *boundaries, FILE *ways)
{
struct item_bin *ib;
@@ -201,7 +213,9 @@ process_boundaries(FILE *boundaries, FILE *ways)
l=g_list_next(l);
}
+#if 0
printf("hierarchy\n");
+#endif
boundaries_list=g_list_sort(boundaries_list, boundary_bbox_compare);
l=boundaries_list;
while (l) {
@@ -212,16 +226,20 @@ process_boundaries(FILE *boundaries, FILE *ways)
if (bbox_contains_bbox(&boundary2->r, &boundary->r)) {
boundaries_list=g_list_remove(boundaries_list, boundary);
boundary2->children=g_list_append(boundary2->children, boundary);
+#if 0
printf("found\n");
+#endif
break;
}
l2=g_list_next(l2);
}
l=ln;
}
+#if 0
printf("hierarchy done\n");
dump_hierarchy(boundaries_list,"");
printf("test\n");
test(boundaries_list);
- return 1;
+#endif
+ return boundaries_list;
}
diff --git a/navit/maptool/maptool.c b/navit/maptool/maptool.c
index 859334b21..622d78ce9 100644
--- a/navit/maptool/maptool.c
+++ b/navit/maptool/maptool.c
@@ -53,6 +53,7 @@ int slices;
int unknown_country;
int doway2poi=1;
char ch_suffix[] ="r"; /* Used to make compiler happy due to Bug 35903 in gcc */
+int experimental;
struct buffer node_buffer = {
64*1024*1024,
@@ -124,6 +125,7 @@ usage(FILE *f)
fprintf(f,"-d (--db) <conn. string> : get osm data out of a postgresql database with osm simple scheme and given connect string\n");
#endif
fprintf(f,"-e (--end) <phase> : end at specified phase\n");
+ fprintf(f,"-E (--experimental) : Enable experimental features\n");
fprintf(f,"-i (--input-file) <file> : specify the input file name (OSM), overrules default stdin\n");
fprintf(f,"-k (--keep-tmpfiles) : do not delete tmp files after processing. useful to reuse them\n\n");
fprintf(f,"-M (--o5m) : input file os o5m\n");
@@ -200,6 +202,7 @@ parse_option(struct maptool_params *p, char **argv, int argc, int *option_index)
{"dump", 0, 0, 'D'},
{"dump-coordinates", 0, 0, 'c'},
{"end", 1, 0, 'e'},
+ {"experimental", 0, 0, 'E'},
{"help", 0, 0, 'h'},
{"keep-tmpfiles", 0, 0, 'k'},
{"nodes-only", 0, 0, 'N'},
@@ -218,7 +221,7 @@ parse_option(struct maptool_params *p, char **argv, int argc, int *option_index)
{"unknown-country", 0, 0, 'U'},
{0, 0, 0, 0}
};
- c = getopt_long (argc, argv, "5:6B:DMNO:PS:Wa:bc"
+ c = getopt_long (argc, argv, "5:6B:DEMNO:PS:Wa:bc"
#ifdef HAVE_POSTGRESQL
"d:"
#endif
@@ -238,6 +241,9 @@ parse_option(struct maptool_params *p, char **argv, int argc, int *option_index)
case 'D':
p->output=1;
break;
+ case 'E':
+ experimental=1;
+ break;
case 'M':
p->o5m=1;
break;
@@ -810,9 +816,17 @@ int main(int argc, char **argv)
}
phase++;
if (p.start <= phase && p.end >= phase) {
- FILE *towns=tempfile(suffix,"towns",0);
+ FILE *towns=tempfile(suffix,"towns",0),*boundaries=NULL,*ways=NULL;
+ if (experimental) {
+ boundaries=tempfile(suffix,"boundaries",0);
+ ways=tempfile(suffix,"ways_split",0);
+ }
fprintf(stderr,"PROGRESS: Phase %d: assinging towns to countries\n",phase);
- osm_process_towns(towns);
+ osm_process_towns(towns,boundaries,ways);
+ if (experimental) {
+ fclose(ways);
+ fclose(boundaries);
+ }
fclose(towns);
if(!p.keep_tmpfiles)
tempfile_unlink(suffix,"towns");
diff --git a/navit/maptool/maptool.h b/navit/maptool/maptool.h
index 0886dde03..a487b4333 100644
--- a/navit/maptool/maptool.h
+++ b/navit/maptool/maptool.h
@@ -102,9 +102,21 @@ struct item_bin_sink {
struct zip_info;
+struct country_table;
+
/* boundaries.c */
-int process_boundaries(FILE *boundaries, FILE *ways);
+struct boundary {
+ struct item_bin *ib;
+ struct country_table *country;
+ GList *segments,*sorted_segments;
+ GList *children;
+ struct rect r;
+};
+
+GList *process_boundaries(FILE *boundaries, FILE *ways);
+
+GList *boundary_find_matches(GList *bl, struct coord *c);
/* buffer.c */
struct buffer {
@@ -211,6 +223,7 @@ extern struct item_bin *item_bin;
extern int bytes_read;
extern int overlap;
extern int unknown_country;
+extern int experimental;
void sig_alrm(int sig);
void sig_alrm_end(void);
@@ -245,6 +258,7 @@ struct maptool_osm {
FILE *towns;
};
+void osm_warning(char *type, long long id, int cont, char *fmt, ...);
void osm_add_tag(char *k, char *v);
void osm_add_node(osmid id, double lat, double lon);
void osm_add_way(osmid id);
@@ -261,13 +275,17 @@ void process_turn_restrictions(FILE *in, FILE *coords, FILE *ways, FILE *ways_in
void clear_node_item_buffer(void);
void ref_ways(FILE *in);
void resolve_ways(FILE *in, FILE *out);
+long long item_bin_get_nodeid(struct item_bin *ib);
+long long item_bin_get_wayid(struct item_bin *ib);
+long long item_bin_get_relationid(struct item_bin *ib);
FILE *resolve_ways_file(FILE *in, char *suffix, char *filename);
void process_way2poi(FILE *in, FILE *out, int type);
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 osm_process_towns(FILE *in);
+void osm_process_towns(FILE *in, FILE *boundaries, FILE *ways);
void load_countries(void);
void remove_countryfiles(void);
+struct country_table * country_from_iso2(char *iso);
void osm_init(FILE*);
/* osm_o5m.c */
diff --git a/navit/maptool/osm.c b/navit/maptool/osm.c
index 7d11df0f9..045342e26 100644
--- a/navit/maptool/osm.c
+++ b/navit/maptool/osm.c
@@ -23,6 +23,7 @@
#include "maptool.h"
#include "debug.h"
#include "linguistics.h"
+#include "country.h"
#include "file.h"
extern int doway2poi;
@@ -822,7 +823,8 @@ build_countrytable(void)
}
}
}
-static void
+
+void
osm_warning(char *type, long long id, int cont, char *fmt, ...)
{
char str[4096];
@@ -848,7 +850,7 @@ attr_strings_save(enum attr_strings id, char *str)
attr_strings_buffer_len+=strlen(str)+1;
}
-static long long
+long long
item_bin_get_nodeid(struct item_bin *ib)
{
long long *ret=item_bin_get_attr(ib, attr_osm_nodeid, NULL);
@@ -857,7 +859,7 @@ item_bin_get_nodeid(struct item_bin *ib)
return 0;
}
-static long long
+long long
item_bin_get_wayid(struct item_bin *ib)
{
long long *ret=item_bin_get_attr(ib, attr_osm_wayid, NULL);
@@ -866,7 +868,7 @@ item_bin_get_wayid(struct item_bin *ib)
return 0;
}
-static long long
+long long
item_bin_get_relationid(struct item_bin *ib)
{
long long *ret=item_bin_get_attr(ib, attr_osm_relationid, NULL);
@@ -1436,6 +1438,43 @@ osm_add_relation(osmid id)
item_bin_add_attr_longlong(item_bin, attr_osm_relationid, current_id);
}
+static int
+country_id_from_iso2(char *iso)
+{
+ int ret=0;
+ if (iso) {
+ struct country_search *search;
+ struct attr country_iso2,country_id;
+ struct item *item;
+ country_iso2.type=attr_country_iso2;
+ country_iso2.u.str=iso;
+ search=country_search_new(&country_iso2,0);
+ if ((item=country_search_get_item(search)) && item_attr_get(item, attr_country_id, &country_id))
+ ret=country_id.u.num;
+
+ country_search_destroy(search);
+ }
+ return ret;
+}
+
+static struct country_table *
+country_from_countryid(int id)
+{
+ int i;
+ for (i = 0 ; i < sizeof(country_table)/sizeof(struct country_table) ; i++) {
+ if (country_table[i].countryid == id)
+ return &country_table[i];
+ }
+ return NULL;
+}
+
+struct country_table *
+country_from_iso2(char *iso)
+{
+ return country_from_countryid(country_id_from_iso2(iso));
+}
+
+
void
osm_end_relation(struct maptool_osm *osm)
{
@@ -1500,13 +1539,13 @@ relation_add_tag(char *k, char *v)
} else if (!strcmp(k,"ISO3166-1")) {
strcpy(iso_code, v);
}
-#if 0
- if (add_tag) {
- char tag[strlen(k)+strlen(v)+2];
- sprintf(tag,"%s=%s",k,v);
- item_bin_add_attr_string(item_bin, attr_osm_tag, tag);
+ if (experimental) {
+ if (add_tag) {
+ char tag[strlen(k)+strlen(v)+2];
+ sprintf(tag,"%s=%s",k,v);
+ item_bin_add_attr_string(item_bin, attr_osm_tag, tag);
+ }
}
-#endif
}
@@ -1685,30 +1724,77 @@ osm_end_node(struct maptool_osm *osm)
attr_longest_match_clear();
}
+static struct country_table *
+osm_process_town_unknown_country(void)
+{
+ static struct country_table *unknown;
+ if (!unknown)
+ unknown=country_from_countryid(999);
+
+ return unknown;
+}
+
+static struct country_table *
+osm_process_town_by_is_in(char *is_in)
+{
+ struct country_table *result=NULL, *lookup;
+ char *tok,*dup=g_strdup(is_in),*buf=dup;
+ int conflict;
+
+ 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;
+ }
+ result=lookup;
+ }
+ buf=NULL;
+ }
+ g_free(dup);
+ return result;
+}
+
+static struct country_table *
+osm_process_town_by_boundary(GList *bl, struct coord *c)
+{
+ GList *l,*matches=boundary_find_matches(bl, c);
+ struct country_table *match=NULL;
+
+ l=matches;
+ while (l) {
+ struct boundary *b=l->data;
+ if (b->country) {
+ if (match)
+ printf("conflict %d vs %d\n",b->country->countryid,match->countryid);
+ match=b->country;
+ }
+ l=g_list_next(l);
+ }
+ return match;
+}
+
void
-osm_process_towns(FILE *in)
+osm_process_towns(FILE *in, FILE *boundaries, FILE *ways)
{
struct item_bin *ib;
+ GList *bl=NULL;
+ if (experimental)
+ bl=process_boundaries(boundaries, ways);
while ((ib=read_item(in))) {
- struct country_table *result=NULL, *lookup;
- char *tok,*is_in=item_bin_get_attr(ib, attr_osm_is_in, NULL), *buf=g_strdup(is_in);
- int conflict;
- if (!buf && unknown_country)
- buf=g_strdup("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;
- }
- result=lookup;
- }
- buf=NULL;
- }
+ struct coord *c=(struct coord *)(ib+1);
+ struct country_table *result=NULL;
+ char *is_in=item_bin_get_attr(ib, attr_osm_is_in, NULL);
+ if (experimental)
+ result=osm_process_town_by_boundary(bl, c);
+ if (!result)
+ result=osm_process_town_by_is_in(is_in);
+ if (!result && unknown_country)
+ result=osm_process_town_unknown_country();
if (result) {
if (!result->file) {
char *name=g_strdup_printf("country_%d.unsorted.tmp", result->countryid);
@@ -1721,7 +1807,6 @@ osm_process_towns(FILE *in)
item_bin_write_match(ib, attr_town_name, attr_town_name_match, result->file);
}
}
- g_free(buf);
}
}
@@ -2006,6 +2091,7 @@ process_turn_restrictions(FILE *in, FILE *coords, FILE *ways, FILE *ways_index,
}
}
+#if 0
static void
process_countries(FILE *way, FILE *ways_index)
{
@@ -2056,6 +2142,7 @@ process_countries(FILE *way, FILE *ways_index)
fclose(tmp);
fclose(in);
}
+#endif
static void
node_ref_way(osmid node)