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 154 by harbaum, Tue Mar 31 06:31:53 2009 UTC
# Line 35  Line 35 
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) {
# Line 1903  void osm_relation_delete(osm_t *osm, rel Line 1897  void osm_relation_delete(osm_t *osm, rel
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 */
# Line 1921  void osm_way_revert(way_t *way) { Line 1915  void osm_way_revert(way_t *way) {
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;
# Line 2089  gint osm_relation_members_num(relation_t Line 2215  gint osm_relation_members_num(relation_t
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

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