35 |
#error "Tree not enabled in libxml" |
#error "Tree not enabled in libxml" |
36 |
#endif |
#endif |
37 |
|
|
|
/* determine where a node/way/relation read from the osm file */ |
|
|
/* is inserted into the internal database */ |
|
|
// #define OSM_SORT_ID |
|
|
#define OSM_SORT_LAST |
|
|
// #define OSM_SORT_FIRST |
|
|
|
|
38 |
/* ------------------------- bounds handling --------------------- */ |
/* ------------------------- bounds handling --------------------- */ |
39 |
|
|
40 |
static void osm_bounds_free(bounds_t *bounds) { |
static void osm_bounds_free(bounds_t *bounds) { |
1897 |
} |
} |
1898 |
} |
} |
1899 |
|
|
1900 |
void osm_way_revert(way_t *way) { |
void osm_way_reverse(way_t *way) { |
1901 |
node_chain_t *new = NULL; |
node_chain_t *new = NULL; |
1902 |
|
|
1903 |
/* walk old chain first to last */ |
/* walk old chain first to last */ |
1915 |
way->node_chain = new; |
way->node_chain = new; |
1916 |
} |
} |
1917 |
|
|
1918 |
|
static const char *DS_ONEWAY_FWD = "yes"; |
1919 |
|
static const char *DS_ONEWAY_REV = "-1"; |
1920 |
|
static const char *DS_LEFT_SUFFIX = ":left"; |
1921 |
|
static const char *DS_RIGHT_SUFFIX = ":right"; |
1922 |
|
|
1923 |
|
/* Reverse direction-sensitive tags like "oneway". Marks the way as dirty if |
1924 |
|
* anything is changed, and returns the number of flipped tags. */ |
1925 |
|
|
1926 |
|
guint |
1927 |
|
osm_way_reverse_direction_sensitive_tags (way_t *way) { |
1928 |
|
tag_t *tag = way->tag; |
1929 |
|
guint n_tags_altered = 0; |
1930 |
|
while (tag != NULL) { |
1931 |
|
char *lc_key = g_ascii_strdown(tag->key, -1); |
1932 |
|
char *lc_value = g_ascii_strdown(tag->value, -1); |
1933 |
|
|
1934 |
|
if (strcmp(lc_key, "oneway") == 0) { |
1935 |
|
// oneway={yes/true/1/-1} is unusual. |
1936 |
|
// Favour "yes" and "-1". |
1937 |
|
if ((strcmp(lc_value, DS_ONEWAY_FWD) == 0) || |
1938 |
|
(strcmp(lc_value, "true") == 0) || |
1939 |
|
(strcmp(lc_value, "1") == 0)) { |
1940 |
|
g_free(tag->value); |
1941 |
|
tag->value = g_strdup(DS_ONEWAY_REV); |
1942 |
|
n_tags_altered++; |
1943 |
|
} |
1944 |
|
else if (strcmp(lc_value, DS_ONEWAY_REV) == 0) { |
1945 |
|
g_free(tag->value); |
1946 |
|
tag->value = g_strdup(DS_ONEWAY_FWD); |
1947 |
|
n_tags_altered++; |
1948 |
|
} |
1949 |
|
else { |
1950 |
|
printf("warning: unknown tag: %s=%s\n", tag->key, tag->value); |
1951 |
|
} |
1952 |
|
} |
1953 |
|
|
1954 |
|
// :left and :right suffixes |
1955 |
|
else if (g_str_has_suffix(lc_key, DS_LEFT_SUFFIX)) { |
1956 |
|
char *key_old = tag->key; |
1957 |
|
char *lastcolon = rindex(key_old, ':'); |
1958 |
|
g_assert(lastcolon != NULL); |
1959 |
|
*lastcolon = '\000'; |
1960 |
|
tag->key = g_strconcat(key_old, DS_RIGHT_SUFFIX, NULL); |
1961 |
|
*lastcolon = ':'; |
1962 |
|
g_free(key_old); |
1963 |
|
n_tags_altered++; |
1964 |
|
} |
1965 |
|
else if (g_str_has_suffix(lc_key, DS_RIGHT_SUFFIX)) { |
1966 |
|
char *key_old = tag->key; |
1967 |
|
char *lastcolon = rindex(key_old, ':'); |
1968 |
|
g_assert(lastcolon != NULL); |
1969 |
|
*lastcolon = '\000'; |
1970 |
|
tag->key = g_strconcat(key_old, DS_LEFT_SUFFIX, NULL); |
1971 |
|
*lastcolon = ':'; |
1972 |
|
g_free(key_old); |
1973 |
|
n_tags_altered++; |
1974 |
|
} |
1975 |
|
|
1976 |
|
g_free(lc_key); |
1977 |
|
g_free(lc_value); |
1978 |
|
tag = tag->next; |
1979 |
|
} |
1980 |
|
if (n_tags_altered > 0) { |
1981 |
|
way->flags |= OSM_FLAG_DIRTY; |
1982 |
|
} |
1983 |
|
return n_tags_altered; |
1984 |
|
} |
1985 |
|
|
1986 |
|
/* Reverse a way's role within relations where the role is direction-sensitive. |
1987 |
|
* Returns the number of roles flipped, and marks any relations changed as |
1988 |
|
* dirty. */ |
1989 |
|
|
1990 |
|
static const char *DS_ROUTE_FORWARD = "forward"; |
1991 |
|
static const char *DS_ROUTE_REVERSE = "reverse"; |
1992 |
|
|
1993 |
|
guint |
1994 |
|
osm_way_reverse_direction_sensitive_roles(osm_t *osm, way_t *way) { |
1995 |
|
relation_chain_t *rel_chain0, *rel_chain; |
1996 |
|
rel_chain0 = rel_chain = osm_way_to_relation(osm, way); |
1997 |
|
guint n_roles_flipped = 0; |
1998 |
|
|
1999 |
|
for (; rel_chain != NULL; rel_chain = rel_chain->next) { |
2000 |
|
char *type = osm_tag_get_by_key(rel_chain->relation->tag, "type"); |
2001 |
|
|
2002 |
|
// Route relations; http://wiki.openstreetmap.org/wiki/Relation:route |
2003 |
|
if (strcasecmp(type, "route") == 0) { |
2004 |
|
|
2005 |
|
// First find the member corresponding to our way: |
2006 |
|
member_t *member = rel_chain->relation->member; |
2007 |
|
for (; member != NULL; member = member->next) { |
2008 |
|
if (member->type == WAY) { |
2009 |
|
if (member->way == way) |
2010 |
|
break; |
2011 |
|
} |
2012 |
|
if (member->type == WAY_ID) { |
2013 |
|
if (member->id == way->id) |
2014 |
|
break; |
2015 |
|
} |
2016 |
|
} |
2017 |
|
g_assert(member); // osm_way_to_relation() broken? |
2018 |
|
|
2019 |
|
// Then flip its role if it's one of the direction-sensitive ones |
2020 |
|
if (member->role == NULL) { |
2021 |
|
printf("null role in route relation -> ignore\n"); |
2022 |
|
} |
2023 |
|
else if (strcasecmp(member->role, DS_ROUTE_FORWARD) == 0) { |
2024 |
|
g_free(member->role); |
2025 |
|
member->role = g_strdup(DS_ROUTE_REVERSE); |
2026 |
|
rel_chain->relation->flags |= OSM_FLAG_DIRTY; |
2027 |
|
++n_roles_flipped; |
2028 |
|
} |
2029 |
|
else if (strcasecmp(member->role, DS_ROUTE_REVERSE) == 0) { |
2030 |
|
g_free(member->role); |
2031 |
|
member->role = g_strdup(DS_ROUTE_FORWARD); |
2032 |
|
rel_chain->relation->flags |= OSM_FLAG_DIRTY; |
2033 |
|
++n_roles_flipped; |
2034 |
|
} |
2035 |
|
|
2036 |
|
// TODO: what about numbered stops? Guess we ignore them; there's no |
2037 |
|
// consensus about whether they should be placed on the way or to one side |
2038 |
|
// of it. |
2039 |
|
|
2040 |
|
}//if-route |
2041 |
|
|
2042 |
|
|
2043 |
|
} |
2044 |
|
if (rel_chain0) { |
2045 |
|
g_free(rel_chain0); |
2046 |
|
} |
2047 |
|
return n_roles_flipped; |
2048 |
|
} |
2049 |
|
|
2050 |
node_t *osm_way_get_first_node(way_t *way) { |
node_t *osm_way_get_first_node(way_t *way) { |
2051 |
node_chain_t *chain = way->node_chain; |
node_chain_t *chain = way->node_chain; |
2052 |
if(!chain) return NULL; |
if(!chain) return NULL; |
2215 |
return num; |
return num; |
2216 |
} |
} |
2217 |
|
|
2218 |
|
void osm_object_set_flags(object_t *object, int set, int clr) { |
2219 |
|
|
2220 |
|
switch(object->type) { |
2221 |
|
case NODE: |
2222 |
|
object->node->flags |= set; |
2223 |
|
object->node->flags &= ~clr; |
2224 |
|
break; |
2225 |
|
|
2226 |
|
case WAY: |
2227 |
|
object->way->flags |= set; |
2228 |
|
object->way->flags &= ~clr; |
2229 |
|
break; |
2230 |
|
|
2231 |
|
case RELATION: |
2232 |
|
object->relation->flags |= set; |
2233 |
|
object->relation->flags &= ~clr; |
2234 |
|
break; |
2235 |
|
|
2236 |
|
default: |
2237 |
|
g_assert(0); |
2238 |
|
break; |
2239 |
|
} |
2240 |
|
} |
2241 |
|
|
2242 |
// vim:et:ts=8:sw=2:sts=2:ai |
// vim:et:ts=8:sw=2:sts=2:ai |