Diff of /trunk/src/osm.c

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

revision 158 by harbaum, Fri Apr 10 11:13:26 2009 UTC revision 234 by harbaum, Mon Jul 20 20:15:10 2009 UTC
# Line 227  void osm_node_dump(node_t *node) { Line 227  void osm_node_dump(node_t *node) {
227    char buf[64];    char buf[64];
228    struct tm tm;    struct tm tm;
229    
230    printf("Id:      %lu\n", node->id);    printf("Id:      "ITEM_ID_FORMAT"\n", node->id);
231    printf("User:    %s\n", node->user?node->user->name:"<unspecified>");    printf("User:    %s\n", node->user?node->user->name:"<unspecified>");
232    printf("Visible: %s\n", node->visible?"yes":"no");    printf("Visible: %s\n", node->visible?"yes":"no");
233    
# Line 260  void osm_node_chain_free(node_chain_t *n Line 260  void osm_node_chain_free(node_chain_t *n
260  }  }
261    
262  void osm_way_free(way_t *way) {  void osm_way_free(way_t *way) {
263    //  printf("freeing way #%ld\n", way->id);    //  printf("freeing way #" ITEM_ID_FORMAT "\n", way->id);
264    
265    osm_node_chain_free(way->node_chain);    osm_node_chain_free(way->node_chain);
266    osm_tags_free(way->tag);    osm_tags_free(way->tag);
# Line 305  void osm_way_dump(way_t *way) { Line 305  void osm_way_dump(way_t *way) {
305    char buf[64];    char buf[64];
306    struct tm tm;    struct tm tm;
307    
308    printf("Id:      %lu\n", way->id);    printf("Id:      "ITEM_ID_FORMAT"\n", way->id);
309    printf("User:    %s\n", way->user?way->user->name:"<unspecified>");    printf("User:    %s\n", way->user?way->user->name:"<unspecified>");
310    printf("Visible: %s\n", way->visible?"yes":"no");    printf("Visible: %s\n", way->visible?"yes":"no");
311    node_chain_t *node_chain = way->node_chain;    node_chain_t *node_chain = way->node_chain;
312    while(node_chain) {    while(node_chain) {
313      printf("  Node:  %lu\n", node_chain->node->id);      printf("  Node:  "ITEM_ID_FORMAT"\n", node_chain->node->id);
314      node_chain = node_chain->next;      node_chain = node_chain->next;
315    }    }
316    
# Line 339  node_chain_t *osm_parse_osm_way_nd(osm_t Line 339  node_chain_t *osm_parse_osm_way_nd(osm_t
339    
340      /* search matching node */      /* search matching node */
341      node_chain->node = osm_get_node_by_id(osm, id);      node_chain->node = osm_get_node_by_id(osm, id);
342      if(!node_chain->node) printf("Node id %lu not found\n", id);      if(!node_chain->node) printf("Node id " ITEM_ID_FORMAT " not found\n", id);
343      else                  node_chain->node->ways++;      else                  node_chain->node->ways++;
344    
345      xmlFree(prop);      xmlFree(prop);
# Line 386  void osm_relations_dump(relation_t *rela Line 386  void osm_relations_dump(relation_t *rela
386      char buf[64];      char buf[64];
387      struct tm tm;      struct tm tm;
388    
389      printf("Id:      %lu\n", relation->id);      printf("Id:      "ITEM_ID_FORMAT"\n", relation->id);
390      printf("User:    %s\n",      printf("User:    %s\n",
391             relation->user?relation->user->name:"<unspecified>");             relation->user?relation->user->name:"<unspecified>");
392      printf("Visible: %s\n", relation->visible?"yes":"no");      printf("Visible: %s\n", relation->visible?"yes":"no");
# Line 402  void osm_relations_dump(relation_t *rela Line 402  void osm_relations_dump(relation_t *rela
402    
403        case NODE:        case NODE:
404          if(member->object.node)          if(member->object.node)
405            printf(" Member: Node, id = %lu, role = %s\n",            printf(" Member: Node, id = " ITEM_ID_FORMAT ", role = %s\n",
406                   member->object.node->id, member->role);                   member->object.node->id, member->role);
407          break;          break;
408    
409        case WAY:        case WAY:
410          if(member->object.way)          if(member->object.way)
411          printf(" Member: Way, id = %lu, role = %s\n",            printf(" Member: Way, id = " ITEM_ID_FORMAT ", role = %s\n",
412                 member->object.way->id, member->role);                   member->object.way->id, member->role);
413          break;          break;
414    
415        case RELATION:        case RELATION:
416          if(member->object.relation)          if(member->object.relation)
417          printf(" Member: Relation, id = %lu, role = %s\n",            printf(" Member: Relation, id = " ITEM_ID_FORMAT ", role = %s\n",
418                 member->object.relation->id, member->role);                   member->object.relation->id, member->role);
419          break;          break;
420        }        }
421    
# Line 759  static node_chain_t *process_nd(xmlTextR Line 759  static node_chain_t *process_nd(xmlTextR
759    
760      /* search matching node */      /* search matching node */
761      node_chain->node = osm_get_node_by_id(osm, id);      node_chain->node = osm_get_node_by_id(osm, id);
762      if(!node_chain->node) printf("Node id %lu not found\n", id);      if(!node_chain->node) printf("Node id " ITEM_ID_FORMAT " not found\n", id);
763      else                  node_chain->node->ways++;      else                  node_chain->node->ways++;
764    
765      xmlFree(prop);      xmlFree(prop);
# 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) {
1264          xmlNodePtr nd_node = xmlNewChild(way_node, NULL, BAD_CAST "nd", NULL);          xmlNodePtr nd_node = xmlNewChild(way_node, NULL, BAD_CAST "nd", NULL);
1265          char *str = g_strdup_printf("%ld", node_chain->node->id);          char *str = g_strdup_printf(ITEM_ID_FORMAT, node_chain->node->id);
1266          xmlNewProp(nd_node, BAD_CAST "ref", BAD_CAST str);          xmlNewProp(nd_node, BAD_CAST "ref", BAD_CAST str);
1267          g_free(str);          g_free(str);
1268          node_chain = node_chain->next;          node_chain = node_chain->next;
# 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 1294  static char *osm_generate_xml(osm_t *osm Line 1292  static char *osm_generate_xml(osm_t *osm
1292          switch(member->object.type) {          switch(member->object.type) {
1293          case NODE:          case NODE:
1294            xmlNewProp(m_node, BAD_CAST "type", BAD_CAST "node");            xmlNewProp(m_node, BAD_CAST "type", BAD_CAST "node");
1295            str = g_strdup_printf("%ld", member->object.node->id);            str = g_strdup_printf(ITEM_ID_FORMAT, member->object.node->id);
1296            break;            break;
1297    
1298          case WAY:          case WAY:
1299            xmlNewProp(m_node, BAD_CAST "type", BAD_CAST "way");            xmlNewProp(m_node, BAD_CAST "type", BAD_CAST "way");
1300            str = g_strdup_printf("%ld", member->object.way->id);            str = g_strdup_printf(ITEM_ID_FORMAT, member->object.way->id);
1301            break;            break;
1302    
1303          case RELATION:          case RELATION:
1304            xmlNewProp(m_node, BAD_CAST "type", BAD_CAST "relation");            xmlNewProp(m_node, BAD_CAST "type", BAD_CAST "relation");
1305            str = g_strdup_printf("%ld", member->object.relation->id);            str = g_strdup_printf(ITEM_ID_FORMAT, member->object.relation->id);
1306            break;            break;
1307    
1308          default:          default:
# 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 1608  way_chain_t *osm_node_delete(osm_t *osm, Line 1592  way_chain_t *osm_node_delete(osm_t *osm,
1592    
1593    /* new nodes aren't stored on the server and are just deleted permanently */    /* new nodes aren't stored on the server and are just deleted permanently */
1594    if(node->flags & OSM_FLAG_NEW) {    if(node->flags & OSM_FLAG_NEW) {
1595      printf("About to delete NEW node #%ld -> force permanent delete\n",      printf("About to delete NEW node #" ITEM_ID_FORMAT
1596             node->id);             " -> force permanent delete\n", node->id);
1597      permanently = TRUE;      permanently = TRUE;
1598    }    }
1599    
# Line 1645  way_chain_t *osm_node_delete(osm_t *osm, Line 1629  way_chain_t *osm_node_delete(osm_t *osm,
1629    }    }
1630    
1631    if(!permanently) {    if(!permanently) {
1632      printf("mark node #%ld as deleted\n", node->id);      printf("mark node #" ITEM_ID_FORMAT " as deleted\n", node->id);
1633      node->flags |= OSM_FLAG_DELETED;      node->flags |= OSM_FLAG_DELETED;
1634    } else {    } else {
1635      printf("permanently delete node #%ld\n", node->id);      printf("permanently delete node #" ITEM_ID_FORMAT "\n", node->id);
1636    
1637      /* remove it from the chain */      /* remove it from the chain */
1638      node_t **cnode = &osm->node;      node_t **cnode = &osm->node;
# 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 1801  gboolean osm_position_within_bounds(osm_ Line 1853  gboolean osm_position_within_bounds(osm_
1853  /* be deleted */  /* be deleted */
1854  void osm_node_remove_from_relation(osm_t *osm, node_t *node) {  void osm_node_remove_from_relation(osm_t *osm, node_t *node) {
1855    relation_t *relation = osm->relation;    relation_t *relation = osm->relation;
1856    printf("removing node #%ld from all relations:\n", node->id);    printf("removing node #" ITEM_ID_FORMAT " from all relations:\n", node->id);
1857    
1858    while(relation) {    while(relation) {
1859      member_t **member = &relation->member;      member_t **member = &relation->member;
# Line 1809  void osm_node_remove_from_relation(osm_t Line 1861  void osm_node_remove_from_relation(osm_t
1861        if(((*member)->object.type == NODE) &&        if(((*member)->object.type == NODE) &&
1862           ((*member)->object.node == node)) {           ((*member)->object.node == node)) {
1863    
1864          printf("  from relation #%ld\n", relation->id);          printf("  from relation #" ITEM_ID_FORMAT "\n", relation->id);
1865    
1866          member_t *cur = *member;          member_t *cur = *member;
1867          *member = (*member)->next;          *member = (*member)->next;
# Line 1826  void osm_node_remove_from_relation(osm_t Line 1878  void osm_node_remove_from_relation(osm_t
1878  /* remove the given way from all relations */  /* remove the given way from all relations */
1879  void osm_way_remove_from_relation(osm_t *osm, way_t *way) {  void osm_way_remove_from_relation(osm_t *osm, way_t *way) {
1880    relation_t *relation = osm->relation;    relation_t *relation = osm->relation;
1881    printf("removing way #%ld from all relations:\n", way->id);    printf("removing way #" ITEM_ID_FORMAT " from all relations:\n", way->id);
1882    
1883    while(relation) {    while(relation) {
1884      member_t **member = &relation->member;      member_t **member = &relation->member;
# Line 1834  void osm_way_remove_from_relation(osm_t Line 1886  void osm_way_remove_from_relation(osm_t
1886        if(((*member)->object.type == WAY) &&        if(((*member)->object.type == WAY) &&
1887           ((*member)->object.way == way)) {           ((*member)->object.way == way)) {
1888    
1889          printf("  from relation #%ld\n", relation->id);          printf("  from relation #" ITEM_ID_FORMAT "\n", relation->id);
1890    
1891          member_t *cur = *member;          member_t *cur = *member;
1892          *member = (*member)->next;          *member = (*member)->next;
# 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 1885  void osm_way_delete(osm_t *osm, icon_t * Line 1930  void osm_way_delete(osm_t *osm, icon_t *
1930    
1931    /* new ways aren't stored on the server and are just deleted permanently */    /* new ways aren't stored on the server and are just deleted permanently */
1932    if(way->flags & OSM_FLAG_NEW) {    if(way->flags & OSM_FLAG_NEW) {
1933      printf("About to delete NEW way #%ld -> force permanent delete\n",      printf("About to delete NEW way #" ITEM_ID_FORMAT
1934             way->id);             " -> force permanent delete\n", way->id);
1935      permanently = TRUE;      permanently = TRUE;
1936    }    }
1937    
# Line 1895  void osm_way_delete(osm_t *osm, icon_t * Line 1940  void osm_way_delete(osm_t *osm, icon_t *
1940    while(*chain) {    while(*chain) {
1941    
1942      (*chain)->node->ways--;      (*chain)->node->ways--;
1943      printf("checking node #%ld (still used by %d)\n",      printf("checking node #" ITEM_ID_FORMAT " (still used by %d)\n",
1944             (*chain)->node->id, (*chain)->node->ways);             (*chain)->node->id, (*chain)->node->ways);
1945    
1946      /* this node must only be part of this way */      /* this node must only be part of this way */
# Line 1921  void osm_way_delete(osm_t *osm, icon_t * Line 1966  void osm_way_delete(osm_t *osm, icon_t *
1966    way->node_chain = NULL;    way->node_chain = NULL;
1967    
1968    if(!permanently) {    if(!permanently) {
1969      printf("mark way #%ld as deleted\n", way->id);      printf("mark way #" ITEM_ID_FORMAT " as deleted\n", way->id);
1970      way->flags |= OSM_FLAG_DELETED;      way->flags |= OSM_FLAG_DELETED;
1971    } else {    } else {
1972      printf("permanently delete way #%ld\n", way->id);      printf("permanently delete way #" ITEM_ID_FORMAT "\n", way->id);
1973    
1974      /* remove it from the chain */      /* remove it from the chain */
1975      way_t **cway = &osm->way;      way_t **cway = &osm->way;
# Line 1949  void osm_relation_delete(osm_t *osm, rel Line 1994  void osm_relation_delete(osm_t *osm, rel
1994    /* new relations aren't stored on the server and are just */    /* new relations aren't stored on the server and are just */
1995    /* deleted permanently */    /* deleted permanently */
1996    if(relation->flags & OSM_FLAG_NEW) {    if(relation->flags & OSM_FLAG_NEW) {
1997      printf("About to delete NEW relation #%ld -> force permanent delete\n",      printf("About to delete NEW relation #" ITEM_ID_FORMAT
1998             relation->id);             " -> force permanent delete\n", relation->id);
1999      permanently = TRUE;      permanently = TRUE;
2000    }    }
2001    
# Line 1958  void osm_relation_delete(osm_t *osm, rel Line 2003  void osm_relation_delete(osm_t *osm, rel
2003    /* don't have any reference to the relation they are part of */    /* don't have any reference to the relation they are part of */
2004    
2005    if(!permanently) {    if(!permanently) {
2006      printf("mark relation #%ld as deleted\n", relation->id);      printf("mark relation #" ITEM_ID_FORMAT " as deleted\n", relation->id);
2007      relation->flags |= OSM_FLAG_DELETED;      relation->flags |= OSM_FLAG_DELETED;
2008    } else {    } else {
2009      printf("permanently delete relation #%ld\n", relation->id);      printf("permanently delete relation #" ITEM_ID_FORMAT "\n", relation->id);
2010    
2011      /* remove it from the chain */      /* remove it from the chain */
2012      relation_t **crelation = &osm->relation;      relation_t **crelation = &osm->relation;
# 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    
# Line 2220  char *osm_object_string(object_t *object Line 2352  char *osm_object_string(object_t *object
2352      return g_strdup_printf("%s #<unspec>", type_str);      return g_strdup_printf("%s #<unspec>", type_str);
2353      break;      break;
2354    case NODE:    case NODE:
2355      return g_strdup_printf("%s #%ld", type_str, object->node->id);      return g_strdup_printf("%s #" ITEM_ID_FORMAT, type_str, object->node->id);
2356      break;      break;
2357    case WAY:    case WAY:
2358      return g_strdup_printf("%s #%ld", type_str, object->way->id);      return g_strdup_printf("%s #" ITEM_ID_FORMAT, type_str, object->way->id);
2359      break;      break;
2360    case RELATION:    case RELATION:
2361      return g_strdup_printf("%s #%ld", type_str, object->relation->id);      return g_strdup_printf("%s #" ITEM_ID_FORMAT, type_str,
2362                               object->relation->id);
2363      break;      break;
2364    case NODE_ID:    case NODE_ID:
2365    case WAY_ID:    case WAY_ID:
2366    case RELATION_ID:    case RELATION_ID:
2367      return g_strdup_printf("%s #%ld", type_str, object->id);      return g_strdup_printf("%s #" ITEM_ID_FORMAT, type_str, object->id);
2368      break;      break;
2369    }    }
2370    return NULL;    return NULL;
# Line 2245  char *osm_object_id_string(object_t *obj Line 2378  char *osm_object_id_string(object_t *obj
2378      return NULL;      return NULL;
2379      break;      break;
2380    case NODE:    case NODE:
2381      return g_strdup_printf("#%ld", object->node->id);      return g_strdup_printf("#"ITEM_ID_FORMAT, object->node->id);
2382      break;      break;
2383    case WAY:    case WAY:
2384      return g_strdup_printf("#%ld", object->way->id);      return g_strdup_printf("#"ITEM_ID_FORMAT, object->way->id);
2385      break;      break;
2386    case RELATION:    case RELATION:
2387      return g_strdup_printf("#%ld", object->relation->id);      return g_strdup_printf("#"ITEM_ID_FORMAT, object->relation->id);
2388      break;      break;
2389    case NODE_ID:    case NODE_ID:
2390    case WAY_ID:    case WAY_ID:
2391    case RELATION_ID:    case RELATION_ID:
2392      return g_strdup_printf("#%ld", object->id);      return g_strdup_printf("#"ITEM_ID_FORMAT, object->id);
2393      break;      break;
2394    }    }
2395    return NULL;    return NULL;

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