Diff of /trunk/src/osm.c

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

revision 161 by harbaum, Sat Apr 11 11:28:56 2009 UTC revision 234 by harbaum, Mon Jul 20 20:15:10 2009 UTC
# Line 1065  static osm_t *process_file(const char *f Line 1065  static osm_t *process_file(const char *f
1065    
1066  #include <sys/time.h>  #include <sys/time.h>
1067    
1068  osm_t *osm_parse(char *filename) {  osm_t *osm_parse(char *path, char *filename) {
1069    
1070    struct timeval start;    struct timeval start;
1071    gettimeofday(&start, NULL);    gettimeofday(&start, NULL);
# Line 1073  osm_t *osm_parse(char *filename) { Line 1073  osm_t *osm_parse(char *filename) {
1073    LIBXML_TEST_VERSION;    LIBXML_TEST_VERSION;
1074    
1075    // use stream parser    // use stream parser
1076    osm_t *osm = process_file(filename);    osm_t *osm = NULL;
1077      if(filename[0] == '/')
1078        osm = process_file(filename);
1079      else {
1080        char *full = g_strjoin(NULL, path, filename, NULL);
1081        osm = process_file(full);
1082        g_free(full);
1083      }
1084    
1085    xmlCleanupParser();    xmlCleanupParser();
1086    
1087    struct timeval end;    struct timeval end;
# Line 1169  gboolean osm_node_has_tag(node_t *node) Line 1177  gboolean osm_node_has_tag(node_t *node)
1177    tag_t *tag = node->tag;    tag_t *tag = node->tag;
1178    
1179    /* created_by tags don't count as real tags */    /* created_by tags don't count as real tags */
1180    if(tag && strcasecmp(tag->key, "created_by") == 0)    if(tag && osm_is_creator_tag(tag))
1181      tag = tag->next;      tag = tag->next;
1182    
1183    return tag != NULL;    return tag != NULL;
# Line 1215  static char *osm_generate_xml(osm_t *osm Line 1223  static char *osm_generate_xml(osm_t *osm
1223    
1224    xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");    xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
1225    xmlNodePtr root_node = xmlNewNode(NULL, BAD_CAST "osm");    xmlNodePtr root_node = xmlNewNode(NULL, BAD_CAST "osm");
 #ifndef API06  
   xmlNewProp(root_node, BAD_CAST "version", BAD_CAST "0.5");  
   xmlNewProp(root_node, BAD_CAST "generator", BAD_CAST PACKAGE " v" VERSION);  
 #endif  
1226    xmlDocSetRootElement(doc, root_node);    xmlDocSetRootElement(doc, root_node);
1227    
1228    switch(type) {    switch(type) {
# Line 1232  static char *osm_generate_xml(osm_t *osm Line 1236  static char *osm_generate_xml(osm_t *osm
1236          snprintf(str, sizeof(str), "%u", (unsigned)node->id);          snprintf(str, sizeof(str), "%u", (unsigned)node->id);
1237          xmlNewProp(node_node, BAD_CAST "id", BAD_CAST str);          xmlNewProp(node_node, BAD_CAST "id", BAD_CAST str);
1238        }        }
 #ifdef API06  
1239        snprintf(str, sizeof(str), "%u", (unsigned)node->version);        snprintf(str, sizeof(str), "%u", (unsigned)node->version);
1240        xmlNewProp(node_node, BAD_CAST "version", BAD_CAST str);        xmlNewProp(node_node, BAD_CAST "version", BAD_CAST str);
1241        snprintf(str, sizeof(str), "%u", (unsigned)changeset);        snprintf(str, sizeof(str), "%u", (unsigned)changeset);
1242        xmlNewProp(node_node, BAD_CAST "changeset", BAD_CAST str);        xmlNewProp(node_node, BAD_CAST "changeset", BAD_CAST str);
 #endif  
1243        g_ascii_formatd(str, sizeof(str), LL_FORMAT, node->pos.lat);        g_ascii_formatd(str, sizeof(str), LL_FORMAT, node->pos.lat);
1244        xmlNewProp(node_node, BAD_CAST "lat", BAD_CAST str);        xmlNewProp(node_node, BAD_CAST "lat", BAD_CAST str);
1245        g_ascii_formatd(str, sizeof(str), LL_FORMAT, node->pos.lon);        g_ascii_formatd(str, sizeof(str), LL_FORMAT, node->pos.lon);
# Line 1252  static char *osm_generate_xml(osm_t *osm Line 1254  static char *osm_generate_xml(osm_t *osm
1254        xmlNodePtr way_node = xmlNewChild(root_node, NULL, BAD_CAST "way", NULL);        xmlNodePtr way_node = xmlNewChild(root_node, NULL, BAD_CAST "way", NULL);
1255        snprintf(str, sizeof(str), "%u", (unsigned)way->id);        snprintf(str, sizeof(str), "%u", (unsigned)way->id);
1256        xmlNewProp(way_node, BAD_CAST "id", BAD_CAST str);        xmlNewProp(way_node, BAD_CAST "id", BAD_CAST str);
 #ifdef API06  
1257        snprintf(str, sizeof(str), "%u", (unsigned)way->version);        snprintf(str, sizeof(str), "%u", (unsigned)way->version);
1258        xmlNewProp(way_node, BAD_CAST "version", BAD_CAST str);        xmlNewProp(way_node, BAD_CAST "version", BAD_CAST str);
1259        snprintf(str, sizeof(str), "%u", (unsigned)changeset);        snprintf(str, sizeof(str), "%u", (unsigned)changeset);
1260        xmlNewProp(way_node, BAD_CAST "changeset", BAD_CAST str);        xmlNewProp(way_node, BAD_CAST "changeset", BAD_CAST str);
 #endif  
1261    
1262        node_chain_t *node_chain = way->node_chain;        node_chain_t *node_chain = way->node_chain;
1263        while(node_chain) {        while(node_chain) {
# Line 1279  static char *osm_generate_xml(osm_t *osm Line 1279  static char *osm_generate_xml(osm_t *osm
1279                                          BAD_CAST "relation", NULL);                                          BAD_CAST "relation", NULL);
1280        snprintf(str, sizeof(str), "%u", (unsigned)relation->id);        snprintf(str, sizeof(str), "%u", (unsigned)relation->id);
1281        xmlNewProp(rel_node, BAD_CAST "id", BAD_CAST str);        xmlNewProp(rel_node, BAD_CAST "id", BAD_CAST str);
 #ifdef API06  
1282        snprintf(str, sizeof(str), "%u", (unsigned)relation->version);        snprintf(str, sizeof(str), "%u", (unsigned)relation->version);
1283        xmlNewProp(rel_node, BAD_CAST "version", BAD_CAST str);        xmlNewProp(rel_node, BAD_CAST "version", BAD_CAST str);
1284        snprintf(str, sizeof(str), "%u", (unsigned)changeset);        snprintf(str, sizeof(str), "%u", (unsigned)changeset);
1285        xmlNewProp(rel_node, BAD_CAST "changeset", BAD_CAST str);        xmlNewProp(rel_node, BAD_CAST "changeset", BAD_CAST str);
 #endif  
1286    
1287        member_t *member = relation->member;        member_t *member = relation->member;
1288        while(member) {        while(member) {
# Line 1531  node_t *osm_node_new(osm_t *osm, gint x, Line 1529  node_t *osm_node_new(osm_t *osm, gint x,
1529    node->visible = TRUE;    node->visible = TRUE;
1530    node->time = time(NULL);    node->time = time(NULL);
1531    
 #ifndef API06  
   /* add created_by tag */  
   node->tag = g_new0(tag_t, 1);  
   node->tag->key = g_strdup("created_by");  
   node->tag->value = g_strdup(PACKAGE " v" VERSION);  
 #endif  
   
1532    /* convert screen position back to ll */    /* convert screen position back to ll */
1533    lpos2pos(osm->bounds, &node->lpos, &node->pos);    lpos2pos(osm->bounds, &node->lpos, &node->pos);
1534    
# Line 1578  way_t *osm_way_new(void) { Line 1569  way_t *osm_way_new(void) {
1569    way->flags = OSM_FLAG_NEW;    way->flags = OSM_FLAG_NEW;
1570    way->time = time(NULL);    way->time = time(NULL);
1571    
 #ifndef API06  
   /* add created_by tag */  
   way->tag = g_new0(tag_t, 1);  
   way->tag->key = g_strdup("created_by");  
   way->tag->value = g_strdup(PACKAGE " v" VERSION);  
 #endif  
   
1572    return way;    return way;
1573  }  }
1574    
# Line 1762  relation_chain_t *osm_way_to_relation(os Line 1746  relation_chain_t *osm_way_to_relation(os
1746    return rel_chain;    return rel_chain;
1747  }  }
1748    
1749    /* return all relations a relation is in */
1750    relation_chain_t *osm_relation_to_relation(osm_t *osm, relation_t *rel) {
1751      relation_chain_t *rel_chain = NULL, **cur_rel_chain = &rel_chain;
1752    
1753      relation_t *relation = osm->relation;
1754      while(relation) {
1755        gboolean is_member = FALSE;
1756    
1757        member_t *member = relation->member;
1758        while(member) {
1759          switch(member->object.type) {
1760          case RELATION: {
1761            /* relations can be check directly */
1762            if(member->object.relation == rel)
1763              is_member = TRUE;
1764          } break;
1765    
1766          default:
1767            break;
1768          }
1769          member = member->next;
1770        }
1771    
1772        /* way is a member of this relation, so move it to the member chain */
1773        if(is_member) {
1774          *cur_rel_chain = g_new0(relation_chain_t, 1);
1775          (*cur_rel_chain)->relation = relation;
1776          cur_rel_chain = &((*cur_rel_chain)->next);
1777        }
1778    
1779        relation = relation->next;
1780      }
1781    
1782      return rel_chain;
1783    }
1784    
1785    /* return all relations an object is in */
1786    relation_chain_t *osm_object_to_relation(osm_t *osm, object_t *object) {
1787      relation_chain_t *rel_chain = NULL;
1788    
1789      switch(object->type) {
1790      case NODE:
1791        rel_chain = osm_node_to_relation(osm, object->node);
1792        break;
1793    
1794      case WAY:
1795        rel_chain = osm_way_to_relation(osm, object->way);
1796        break;
1797    
1798      case RELATION:
1799        rel_chain = osm_relation_to_relation(osm, object->relation);
1800        break;
1801    
1802      default:
1803        break;
1804      }
1805    
1806      return rel_chain;
1807    }
1808    
1809    void osm_relation_chain_free(relation_chain_t *rchain) {
1810      while(rchain) {
1811        relation_chain_t *next = rchain->next;
1812        g_free(rchain);
1813        rchain = next;
1814      }
1815    }
1816    
1817  /* return all ways a node is in */  /* return all ways a node is in */
1818  way_chain_t *osm_node_to_way(osm_t *osm, node_t *node) {  way_chain_t *osm_node_to_way(osm_t *osm, node_t *node) {
1819    way_chain_t *chain = NULL, **cur_chain = &chain;    way_chain_t *chain = NULL, **cur_chain = &chain;
# Line 1857  relation_t *osm_relation_new(void) { Line 1909  relation_t *osm_relation_new(void) {
1909    relation->flags = OSM_FLAG_NEW;    relation->flags = OSM_FLAG_NEW;
1910    relation->time = time(NULL);    relation->time = time(NULL);
1911    
 #ifndef API06  
   /* add created_by tag */  
   relation->tag = g_new0(tag_t, 1);  
   relation->tag->key = g_strdup("created_by");  
   relation->tag->value = g_strdup(PACKAGE " v" VERSION);  
 #endif  
   
1912    return relation;    return relation;
1913  }  }
1914    
# Line 2169  void osm_way_rotate(way_t *way, gint off Line 2214  void osm_way_rotate(way_t *way, gint off
2214    }    }
2215  }  }
2216    
2217  tag_t *osm_tags_copy(tag_t *src_tag, gboolean update_creator) {  tag_t *osm_tags_copy(tag_t *src_tag) {
2218    tag_t *new_tags = NULL;    tag_t *new_tags = NULL;
2219    tag_t **dst_tag = &new_tags;    tag_t **dst_tag = &new_tags;
2220    
2221    while(src_tag) {    while(src_tag) {
2222      *dst_tag = g_new0(tag_t, 1);      if(!osm_is_creator_tag(src_tag)) {
2223      (*dst_tag)->key = g_strdup(src_tag->key);        *dst_tag = g_new0(tag_t, 1);
2224      if(update_creator && (strcasecmp(src_tag->key, "created_by") == 0))        (*dst_tag)->key = g_strdup(src_tag->key);
       (*dst_tag)->value = g_strdup(PACKAGE " v" VERSION);  
     else  
2225        (*dst_tag)->value = g_strdup(src_tag->value);        (*dst_tag)->value = g_strdup(src_tag->value);
2226          dst_tag = &(*dst_tag)->next;
2227      dst_tag = &(*dst_tag)->next;      }
2228      src_tag = src_tag->next;      src_tag = src_tag->next;
2229    }    }
2230    
2231    return new_tags;    return new_tags;
2232  }  }
2233    
# Line 2193  char *osm_object_type_string(object_t *o Line 2236  char *osm_object_type_string(object_t *o
2236    const struct { type_t type; char *name; } types[] = {    const struct { type_t type; char *name; } types[] = {
2237      { ILLEGAL,     "illegal" },      { ILLEGAL,     "illegal" },
2238      { NODE,        "node" },      { NODE,        "node" },
2239      { WAY,         "way" },      { WAY,         "way/area" },
2240      { RELATION,    "relation" },      { RELATION,    "relation" },
2241      { NODE_ID,     "node id" },      { NODE_ID,     "node id" },
2242      { WAY_ID,      "way id" },      { WAY_ID,      "way/area id" },
2243      { RELATION_ID, "relation id" },      { RELATION_ID, "relation id" },
2244      { 0, NULL }      { 0, NULL }
2245    };    };
# Line 2209  char *osm_object_type_string(object_t *o Line 2252  char *osm_object_type_string(object_t *o
2252    return NULL;    return NULL;
2253  }  }
2254    
2255    char *osm_object_get_name(object_t *object) {
2256      tag_t *tags = osm_object_get_tags(object);
2257    
2258      if(!tags) return NULL;
2259      return osm_tag_get_by_key(tags, "name");
2260    }
2261    
2262    /* try to get an as "speaking" description of the object as possible */
2263    char *osm_object_get_speaking_name(object_t *object) {
2264      char *ret = NULL;
2265      tag_t *tags = osm_object_get_tags(object);
2266    
2267      /* worst case: we have no tags at all. return techincal info then */
2268      if(!tags)
2269        return g_strdup_printf("unspecified %s", osm_object_type_string(object));
2270    
2271      /* try to figure out _what_ this is */
2272    
2273      char *name = osm_tag_get_by_key(tags, "name");
2274      if(!name) name = osm_tag_get_by_key(tags, "ref");
2275      if(!name) name = osm_tag_get_by_key(tags, "note");
2276      if(!name) name = osm_tag_get_by_key(tags, "fix" "me");
2277      if(!name) name = osm_tag_get_by_key(tags, "sport");
2278    
2279      /* search for some kind of "type" */
2280      gboolean free_type = FALSE;
2281      char *type = osm_tag_get_by_key(tags, "amenity");
2282      if(!type) type = osm_tag_get_by_key(tags, "place");
2283      if(!type) type = osm_tag_get_by_key(tags, "historic");
2284      if(!type) type = osm_tag_get_by_key(tags, "leisure");
2285      if(!type) type = osm_tag_get_by_key(tags, "tourism");
2286      if(!type) type = osm_tag_get_by_key(tags, "landuse");
2287      if(!type) type = osm_tag_get_by_key(tags, "waterway");
2288      if(!type) type = osm_tag_get_by_key(tags, "railway");
2289      if(!type) type = osm_tag_get_by_key(tags, "natural");
2290      if(!type && osm_tag_get_by_key(tags, "building")) type = "building";
2291    
2292      /* highways are a little bit difficult */
2293      char *highway = osm_tag_get_by_key(tags, "highway");
2294      if(highway) {
2295        if((!strcmp(highway, "primary")) ||
2296           (!strcmp(highway, "secondary")) ||
2297           (!strcmp(highway, "tertiary")) ||
2298           (!strcmp(highway, "unclassified")) ||
2299           (!strcmp(highway, "residential")) ||
2300           (!strcmp(highway, "service"))) {
2301          type = g_strdup_printf("%s road", highway);
2302          free_type = TRUE;
2303        }
2304    
2305        else if(!strcmp(highway, "pedestrian")) {
2306          type = g_strdup_printf("%s way/area", highway);
2307          free_type = TRUE;
2308        }
2309    
2310        else if(!strcmp(highway, "construction")) {
2311          type = g_strdup_printf("road/street under %s", highway);
2312          free_type = TRUE;
2313        }
2314    
2315        else
2316          type = highway;
2317      }
2318    
2319      if(type && name)
2320        ret = g_strdup_printf("%s: \"%s\"", type, name);
2321      else if(type && !name)
2322        ret = g_strdup(type);
2323      else if(name && !type)
2324        ret = g_strdup_printf("%s: \"%s\"",
2325              osm_object_type_string(object), name);
2326      else
2327        ret = g_strdup_printf("unspecified %s", osm_object_type_string(object));
2328    
2329      if(free_type)
2330        g_free(type);
2331    
2332      /* remove underscores from string and replace them by spaces as this is */
2333      /* usually nicer */
2334      char *p = ret;
2335      while(*p) {
2336        if(*p == '_')
2337          *p = ' ';
2338        p++;
2339      }
2340    
2341      return ret;
2342    }
2343    
2344  char *osm_object_string(object_t *object) {  char *osm_object_string(object_t *object) {
2345    char *type_str = osm_object_type_string(object);    char *type_str = osm_object_type_string(object);
2346    

Legend:
Removed from v.161  
changed lines
  Added in v.234