Diff of /trunk/src/osm.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 78 by harbaum, Sun Feb 15 12:07:04 2009 UTC revision 98 by achadwick, Sun Feb 22 03:41:09 2009 UTC
# Line 1903  void osm_relation_delete(osm_t *osm, rel Line 1903  void osm_relation_delete(osm_t *osm, rel
1903    }    }
1904  }  }
1905    
1906  void osm_way_revert(way_t *way) {  void osm_way_reverse(way_t *way) {
1907    node_chain_t *new = NULL;    node_chain_t *new = NULL;
1908    
1909    /* walk old chain first to last */    /* walk old chain first to last */
# Line 1921  void osm_way_revert(way_t *way) { Line 1921  void osm_way_revert(way_t *way) {
1921    way->node_chain = new;    way->node_chain = new;
1922  }  }
1923    
1924    static const char *DS_ONEWAY_FWD = "yes";
1925    static const char *DS_ONEWAY_REV = "-1";
1926    static const char *DS_LEFT_SUFFIX = ":left";
1927    static const char *DS_RIGHT_SUFFIX = ":right";
1928    
1929    /* Reverse direction-sensitive tags like "oneway". Marks the way as dirty if
1930     * anything is changed, and returns the number of flipped tags. */
1931    
1932    guint
1933    osm_way_reverse_direction_sensitive_tags (way_t *way) {
1934      tag_t *tag = way->tag;
1935      guint n_tags_altered = 0;
1936      while (tag != NULL) {
1937        char *lc_key = g_ascii_strdown(tag->key, -1);
1938        char *lc_value = g_ascii_strdown(tag->value, -1);
1939    
1940        if (strcmp(lc_key, "oneway") == 0) {
1941          // oneway={yes/true/1/-1} is unusual.
1942          // Favour "yes" and "-1".
1943          if ((strcmp(lc_value, DS_ONEWAY_FWD) == 0) ||
1944              (strcmp(lc_value, "true") == 0) ||
1945              (strcmp(lc_value, "1") == 0)) {
1946            g_free(tag->value);
1947            tag->value = g_strdup(DS_ONEWAY_REV);
1948            n_tags_altered++;
1949          }
1950          else if (strcmp(lc_value, DS_ONEWAY_REV) == 0) {
1951            g_free(tag->value);
1952            tag->value = g_strdup(DS_ONEWAY_FWD);
1953            n_tags_altered++;
1954          }
1955          else {
1956            printf("warning: unknown tag: %s=%s\n", tag->key, tag->value);
1957          }
1958        }
1959    
1960        // :left and :right suffixes
1961        else if (g_str_has_suffix(lc_key, DS_LEFT_SUFFIX)) {
1962          char *key_old = tag->key;
1963          char *lastcolon = rindex(key_old, ':');
1964          g_assert(lastcolon != NULL);
1965          *lastcolon = '\000';
1966          tag->key = g_strconcat(key_old, DS_RIGHT_SUFFIX, NULL);
1967          *lastcolon = ':';
1968          g_free(key_old);
1969          n_tags_altered++;
1970        }
1971        else if (g_str_has_suffix(lc_key, DS_RIGHT_SUFFIX)) {
1972          char *key_old = tag->key;
1973          char *lastcolon = rindex(key_old, ':');
1974          g_assert(lastcolon != NULL);
1975          *lastcolon = '\000';
1976          tag->key = g_strconcat(key_old, DS_LEFT_SUFFIX, NULL);
1977          *lastcolon = ':';
1978          g_free(key_old);
1979          n_tags_altered++;
1980        }
1981    
1982        g_free(lc_key);
1983        g_free(lc_value);
1984        tag = tag->next;
1985      }
1986      if (n_tags_altered > 0) {
1987        way->flags |= OSM_FLAG_DIRTY;
1988      }
1989      return n_tags_altered;
1990    }
1991    
1992    /* Reverse a way's role within relations where the role is direction-sensitive.
1993     * Returns the number of roles flipped, and marks any relations changed as
1994     * dirty. */
1995    
1996    static const char *DS_ROUTE_FORWARD = "forward";
1997    static const char *DS_ROUTE_REVERSE = "reverse";
1998    
1999    guint
2000    osm_way_reverse_direction_sensitive_roles(osm_t *osm, way_t *way) {
2001      relation_chain_t *rel_chain0, *rel_chain;
2002      rel_chain0 = rel_chain = osm_way_to_relation(osm, way);
2003      guint n_roles_flipped = 0;
2004    
2005      for (; rel_chain != NULL; rel_chain = rel_chain->next) {
2006        char *type = osm_tag_get_by_key(rel_chain->relation->tag, "type");
2007    
2008        // Route relations; http://wiki.openstreetmap.org/wiki/Relation:route
2009        if (strcasecmp(type, "route") == 0) {
2010    
2011          // First find the member corresponding to our way:
2012          member_t *member = rel_chain->relation->member;
2013          for (; member != NULL; member = member->next) {
2014            if (member->type == WAY) {
2015              if (member->way == way)
2016                break;
2017            }
2018            if (member->type == WAY_ID) {
2019              if (member->id == way->id)
2020                break;
2021            }
2022          }
2023          g_assert(member);  // osm_way_to_relation() broken?
2024    
2025          // Then flip its role if it's one of the direction-sensitive ones
2026          if (strcasecmp(member->role, DS_ROUTE_FORWARD) == 0) {
2027            g_free(member->role);
2028            member->role = g_strdup(DS_ROUTE_REVERSE);
2029            rel_chain->relation->flags |= OSM_FLAG_DIRTY;
2030            ++n_roles_flipped;
2031          }
2032          else if (strcasecmp(member->role, DS_ROUTE_REVERSE) == 0) {
2033            g_free(member->role);
2034            member->role = g_strdup(DS_ROUTE_FORWARD);
2035            rel_chain->relation->flags |= OSM_FLAG_DIRTY;
2036            ++n_roles_flipped;
2037          }
2038    
2039          // TODO: what about numbered stops? Guess we ignore them; there's no
2040          // consensus about whether they should be placed on the way or to one side
2041          // of it.
2042    
2043        }//if-route
2044    
2045    
2046      }
2047      if (rel_chain0) {
2048        g_free(rel_chain0);
2049      }
2050      return n_roles_flipped;
2051    }
2052    
2053  node_t *osm_way_get_first_node(way_t *way) {  node_t *osm_way_get_first_node(way_t *way) {
2054    node_chain_t *chain = way->node_chain;    node_chain_t *chain = way->node_chain;
2055    if(!chain) return NULL;    if(!chain) return NULL;

Legend:
Removed from v.78  
changed lines
  Added in v.98