17 |
* along with OSM2Go. If not, see <http://www.gnu.org/licenses/>. |
* along with OSM2Go. If not, see <http://www.gnu.org/licenses/>. |
18 |
*/ |
*/ |
19 |
|
|
20 |
/* xml parsing has a performance issue */ |
/* these defines select one of three possible xml parsers */ |
21 |
|
/* this is in fact selected depending on the plattform in the Makefile */ |
22 |
// #define OSM_DOM_PARSER |
// #define OSM_DOM_PARSER |
23 |
// #define OSM_STREAM_PARSER |
// #define OSM_STREAM_PARSER |
|
#define OSM_QND_XML_PARSER |
|
24 |
|
|
25 |
#include <stdio.h> |
#include <stdio.h> |
26 |
#include <stdlib.h> |
#include <stdlib.h> |
370 |
xmlFree(prop); |
xmlFree(prop); |
371 |
} |
} |
372 |
|
|
373 |
|
/* append node to end of hash table if present */ |
374 |
|
if(osm->node_hash) { |
375 |
|
hash_item_t **item = &osm->node_hash->hash[ID2HASH(node->id)]; |
376 |
|
while(*item) item = &(*item)->next; |
377 |
|
|
378 |
|
*item = g_new0(hash_item_t, 1); |
379 |
|
(*item)->data.node = node; |
380 |
|
} |
381 |
|
|
382 |
/* scan for tags and attach a list of tags */ |
/* scan for tags and attach a list of tags */ |
383 |
tag_t **tag = &node->tag; |
tag_t **tag = &node->tag; |
384 |
for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) { |
for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) { |
490 |
node_chain_t *node_chain = g_new0(node_chain_t, 1); |
node_chain_t *node_chain = g_new0(node_chain_t, 1); |
491 |
|
|
492 |
/* search matching node */ |
/* search matching node */ |
493 |
node_chain->node = osm->node; |
node_chain->node = osm_get_node_by_id(osm, id); |
|
while(node_chain->node && node_chain->node->id != id) |
|
|
node_chain->node = node_chain->node->next; |
|
|
|
|
494 |
if(!node_chain->node) printf("Node id %lu not found\n", id); |
if(!node_chain->node) printf("Node id %lu not found\n", id); |
495 |
|
else node_chain->node->ways++; |
|
if(node_chain->node) |
|
|
node_chain->node->ways++; |
|
496 |
|
|
497 |
xmlFree(prop); |
xmlFree(prop); |
498 |
|
|
531 |
xmlFree(prop); |
xmlFree(prop); |
532 |
} |
} |
533 |
|
|
534 |
|
/* append way to end of hash table if present */ |
535 |
|
if(osm->way_hash) { |
536 |
|
hash_item_t **item = &osm->way_hash->hash[ID2HASH(way->id)]; |
537 |
|
while(*item) item = &(*item)->next; |
538 |
|
|
539 |
|
*item = g_new0(hash_item_t, 1); |
540 |
|
(*item)->data.way = way; |
541 |
|
} |
542 |
|
|
543 |
/* scan for tags/nodes and attach their lists */ |
/* scan for tags/nodes and attach their lists */ |
544 |
tag_t **tag = &way->tag; |
tag_t **tag = &way->tag; |
545 |
node_chain_t **node_chain = &way->node_chain; |
node_chain_t **node_chain = &way->node_chain; |
578 |
} |
} |
579 |
} |
} |
580 |
|
|
581 |
|
void osm_relation_free(relation_t *relation) { |
582 |
|
osm_tags_free(relation->tag); |
583 |
|
osm_members_free(relation->member); |
584 |
|
|
585 |
|
g_free(relation); |
586 |
|
} |
587 |
|
|
588 |
static void osm_relations_free(relation_t *relation) { |
static void osm_relations_free(relation_t *relation) { |
589 |
while(relation) { |
while(relation) { |
590 |
relation_t *next = relation->next; |
relation_t *next = relation->next; |
591 |
|
osm_relation_free(relation); |
|
osm_tags_free(relation->tag); |
|
|
osm_members_free(relation->member); |
|
|
|
|
|
g_free(relation); |
|
592 |
relation = next; |
relation = next; |
593 |
} |
} |
594 |
} |
} |
668 |
|
|
669 |
case WAY: |
case WAY: |
670 |
/* search matching way */ |
/* search matching way */ |
671 |
member->way = osm->way; |
member->way = osm_get_way_by_id(osm, id); |
|
while(member->way && member->way->id != id) |
|
|
member->way = member->way->next; |
|
|
|
|
672 |
if(!member->way) { |
if(!member->way) { |
673 |
member->type = WAY_ID; |
member->type = WAY_ID; |
674 |
member->id = id; |
member->id = id; |
677 |
|
|
678 |
case NODE: |
case NODE: |
679 |
/* search matching node */ |
/* search matching node */ |
680 |
member->node = osm->node; |
member->node = osm_get_node_by_id(osm, id); |
|
while(member->node && member->node->id != id) |
|
|
member->node = member->node->next; |
|
|
|
|
681 |
if(!member->node) { |
if(!member->node) { |
682 |
member->type = NODE_ID; |
member->type = NODE_ID; |
683 |
member->id = id; |
member->id = id; |
686 |
|
|
687 |
case RELATION: |
case RELATION: |
688 |
/* search matching relation */ |
/* search matching relation */ |
689 |
member->relation = osm->relation; |
member->relation = osm_get_relation_by_id(osm, id); |
|
while(member->relation && member->relation->id != id) |
|
|
member->relation = member->relation->next; |
|
|
|
|
690 |
if(!member->relation) { |
if(!member->relation) { |
691 |
member->type = NODE_ID; |
member->type = NODE_ID; |
692 |
member->id = id; |
member->id = id; |
762 |
|
|
763 |
/* ----------------------- generic xml handling -------------------------- */ |
/* ----------------------- generic xml handling -------------------------- */ |
764 |
|
|
765 |
/* parse loc entry */ |
/* parse osm entry */ |
766 |
static void osm_parse_osm(osm_t *osm, xmlDocPtr doc, xmlNode * a_node) { |
static void osm_parse_osm(osm_t *osm, xmlDocPtr doc, xmlNode * a_node) { |
767 |
xmlNode *cur_node = NULL; |
xmlNode *cur_node = NULL; |
768 |
|
|
844 |
|
|
845 |
/* allocate memory to hold osm file description */ |
/* allocate memory to hold osm file description */ |
846 |
osm = g_new0(osm_t, 1); |
osm = g_new0(osm_t, 1); |
847 |
|
osm->node_hash = g_new0(hash_table_t, 1); |
848 |
|
osm->way_hash = g_new0(hash_table_t, 1); |
849 |
|
|
850 |
for (cur_node = a_node; cur_node; cur_node = cur_node->next) { |
for (cur_node = a_node; cur_node; cur_node = cur_node->next) { |
851 |
if (cur_node->type == XML_ELEMENT_NODE) { |
if (cur_node->type == XML_ELEMENT_NODE) { |
883 |
|
|
884 |
/* ------------------ osm handling ----------------- */ |
/* ------------------ osm handling ----------------- */ |
885 |
|
|
886 |
|
/* the two hash tables eat over 512kBytes memory and may thus be */ |
887 |
|
/* freed at any time. osm2go can work without them (albeit slower) */ |
888 |
|
static void hash_table_free(hash_table_t *table) { |
889 |
|
if(!table) return; |
890 |
|
|
891 |
|
int i; |
892 |
|
for(i=0;i<65536;i++) { |
893 |
|
hash_item_t *item = table->hash[i]; |
894 |
|
while(item) { |
895 |
|
hash_item_t *next = item->next; |
896 |
|
g_free(item); |
897 |
|
item = next; |
898 |
|
} |
899 |
|
} |
900 |
|
} |
901 |
|
|
902 |
|
void osm_hash_tables_free(osm_t *osm) { |
903 |
|
hash_table_free(osm->node_hash); |
904 |
|
osm->node_hash = NULL; |
905 |
|
hash_table_free(osm->way_hash); |
906 |
|
osm->way_hash = NULL; |
907 |
|
} |
908 |
|
|
909 |
void osm_free(icon_t **icon, osm_t *osm) { |
void osm_free(icon_t **icon, osm_t *osm) { |
910 |
if(!osm) return; |
if(!osm) return; |
911 |
|
|
912 |
|
osm_hash_tables_free(osm); |
913 |
|
|
914 |
if(osm->bounds) osm_bounds_free(osm->bounds); |
if(osm->bounds) osm_bounds_free(osm->bounds); |
915 |
if(osm->user) osm_users_free(osm->user); |
if(osm->user) osm_users_free(osm->user); |
916 |
if(osm->way) osm_ways_free(osm->way); |
if(osm->way) osm_ways_free(osm->way); |
1091 |
|
|
1092 |
pos2lpos(osm->bounds, &node->pos, &node->lpos); |
pos2lpos(osm->bounds, &node->pos, &node->lpos); |
1093 |
|
|
1094 |
|
/* append node to end of hash table if present */ |
1095 |
|
if(osm->node_hash) { |
1096 |
|
hash_item_t **item = &osm->node_hash->hash[ID2HASH(node->id)]; |
1097 |
|
while(*item) item = &(*item)->next; |
1098 |
|
|
1099 |
|
*item = g_new0(hash_item_t, 1); |
1100 |
|
(*item)->data.node = node; |
1101 |
|
} |
1102 |
|
|
1103 |
/* just an empty element? then return the node as it is */ |
/* just an empty element? then return the node as it is */ |
1104 |
if(xmlTextReaderIsEmptyElement(reader)) |
if(xmlTextReaderIsEmptyElement(reader)) |
1105 |
return node; |
return node; |
1137 |
node_chain_t *node_chain = g_new0(node_chain_t, 1); |
node_chain_t *node_chain = g_new0(node_chain_t, 1); |
1138 |
|
|
1139 |
/* search matching node */ |
/* search matching node */ |
1140 |
node_chain->node = osm->node; |
node_chain->node = osm_get_node_by_id(osm, id); |
|
while(node_chain->node && node_chain->node->id != id) |
|
|
node_chain->node = node_chain->node->next; |
|
|
|
|
1141 |
if(!node_chain->node) printf("Node id %lu not found\n", id); |
if(!node_chain->node) printf("Node id %lu not found\n", id); |
1142 |
|
else node_chain->node->ways++; |
|
if(node_chain->node) |
|
|
node_chain->node->ways++; |
|
1143 |
|
|
1144 |
xmlFree(prop); |
xmlFree(prop); |
1145 |
|
|
1176 |
xmlFree(prop); |
xmlFree(prop); |
1177 |
} |
} |
1178 |
|
|
1179 |
|
/* append way to end of hash table if present */ |
1180 |
|
if(osm->way_hash) { |
1181 |
|
hash_item_t **item = &osm->way_hash->hash[ID2HASH(way->id)]; |
1182 |
|
while(*item) item = &(*item)->next; |
1183 |
|
|
1184 |
|
*item = g_new0(hash_item_t, 1); |
1185 |
|
(*item)->data.way = way; |
1186 |
|
} |
1187 |
|
|
1188 |
/* just an empty element? then return the way as it is */ |
/* just an empty element? then return the way as it is */ |
1189 |
/* (this should in fact never happen as this would be a way without nodes) */ |
/* (this should in fact never happen as this would be a way without nodes) */ |
1190 |
if(xmlTextReaderIsEmptyElement(reader)) |
if(xmlTextReaderIsEmptyElement(reader)) |
1240 |
|
|
1241 |
case WAY: |
case WAY: |
1242 |
/* search matching way */ |
/* search matching way */ |
1243 |
member->way = osm->way; |
member->way = osm_get_way_by_id(osm, id); |
|
while(member->way && member->way->id != id) |
|
|
member->way = member->way->next; |
|
|
|
|
1244 |
if(!member->way) { |
if(!member->way) { |
1245 |
member->type = WAY_ID; |
member->type = WAY_ID; |
1246 |
member->id = id; |
member->id = id; |
1249 |
|
|
1250 |
case NODE: |
case NODE: |
1251 |
/* search matching node */ |
/* search matching node */ |
1252 |
member->node = osm->node; |
member->node = osm_get_node_by_id(osm, id); |
|
while(member->node && member->node->id != id) |
|
|
member->node = member->node->next; |
|
|
|
|
1253 |
if(!member->node) { |
if(!member->node) { |
1254 |
member->type = NODE_ID; |
member->type = NODE_ID; |
1255 |
member->id = id; |
member->id = id; |
1258 |
|
|
1259 |
case RELATION: |
case RELATION: |
1260 |
/* search matching relation */ |
/* search matching relation */ |
1261 |
member->relation = osm->relation; |
member->relation = osm_get_relation_by_id(osm, id); |
|
while(member->relation && member->relation->id != id) |
|
|
member->relation = member->relation->next; |
|
|
|
|
1262 |
if(!member->relation) { |
if(!member->relation) { |
1263 |
member->type = NODE_ID; |
member->type = NODE_ID; |
1264 |
member->id = id; |
member->id = id; |
1344 |
static osm_t *process_osm(xmlTextReaderPtr reader) { |
static osm_t *process_osm(xmlTextReaderPtr reader) { |
1345 |
/* alloc osm structure */ |
/* alloc osm structure */ |
1346 |
osm_t *osm = g_new0(osm_t, 1); |
osm_t *osm = g_new0(osm_t, 1); |
1347 |
|
osm->node_hash = g_new0(hash_table_t, 1); |
1348 |
|
osm->way_hash = g_new0(hash_table_t, 1); |
1349 |
|
|
1350 |
node_t **node = &osm->node; |
node_t **node = &osm->node; |
1351 |
way_t **way = &osm->way; |
way_t **way = &osm->way; |
1540 |
/* store current tag pointer in userdata for fast access to current tag */ |
/* store current tag pointer in userdata for fast access to current tag */ |
1541 |
stack->userdata[1] = &node->tag; |
stack->userdata[1] = &node->tag; |
1542 |
|
|
1543 |
|
/* append node to end of hash table if present */ |
1544 |
|
if(osm->node_hash) { |
1545 |
|
hash_item_t **item = &osm->node_hash->hash[ID2HASH(node->id)]; |
1546 |
|
while(*item) item = &(*item)->next; |
1547 |
|
|
1548 |
|
*item = g_new0(hash_item_t, 1); |
1549 |
|
(*item)->data.node = node; |
1550 |
|
} |
1551 |
|
|
1552 |
return TRUE; |
return TRUE; |
1553 |
} |
} |
1554 |
|
|
1564 |
g_new0(node_chain_t, 1); |
g_new0(node_chain_t, 1); |
1565 |
|
|
1566 |
/* search matching node */ |
/* search matching node */ |
1567 |
node_chain->node = osm->node; |
node_chain->node = osm_get_node_by_id(osm, id); |
|
while(node_chain->node && node_chain->node->id != id) |
|
|
node_chain->node = node_chain->node->next; |
|
|
|
|
1568 |
if(!node_chain->node) printf("Node id %lu not found\n", id); |
if(!node_chain->node) printf("Node id %lu not found\n", id); |
1569 |
|
else node_chain->node->ways++; |
|
if(node_chain->node) |
|
|
node_chain->node->ways++; |
|
1570 |
|
|
1571 |
stack->prev->userdata[2] = &node_chain->next; |
stack->prev->userdata[2] = &node_chain->next; |
1572 |
} |
} |
1595 |
stack->userdata[1] = &way->tag; |
stack->userdata[1] = &way->tag; |
1596 |
stack->userdata[2] = &way->node_chain; |
stack->userdata[2] = &way->node_chain; |
1597 |
|
|
1598 |
|
/* append way to end of hash table if present */ |
1599 |
|
if(osm->way_hash) { |
1600 |
|
hash_item_t **item = &osm->way_hash->hash[ID2HASH(way->id)]; |
1601 |
|
while(*item) item = &(*item)->next; |
1602 |
|
|
1603 |
|
*item = g_new0(hash_item_t, 1); |
1604 |
|
(*item)->data.way = way; |
1605 |
|
} |
1606 |
|
|
1607 |
return TRUE; |
return TRUE; |
1608 |
} |
} |
1609 |
|
|
1633 |
|
|
1634 |
case WAY: |
case WAY: |
1635 |
/* search matching way */ |
/* search matching way */ |
1636 |
member->way = osm->way; |
member->way = osm_get_way_by_id(osm, id); |
|
while(member->way && member->way->id != id) |
|
|
member->way = member->way->next; |
|
|
|
|
1637 |
if(!member->way) { |
if(!member->way) { |
1638 |
member->type = WAY_ID; |
member->type = WAY_ID; |
1639 |
member->id = id; |
member->id = id; |
1642 |
|
|
1643 |
case NODE: |
case NODE: |
1644 |
/* search matching node */ |
/* search matching node */ |
1645 |
member->node = osm->node; |
member->node = osm_get_node_by_id(osm, id); |
|
while(member->node && member->node->id != id) |
|
|
member->node = member->node->next; |
|
|
|
|
1646 |
if(!member->node) { |
if(!member->node) { |
1647 |
member->type = NODE_ID; |
member->type = NODE_ID; |
1648 |
member->id = id; |
member->id = id; |
1651 |
|
|
1652 |
case RELATION: |
case RELATION: |
1653 |
/* search matching relation */ |
/* search matching relation */ |
1654 |
member->relation = osm->relation; |
member->relation = osm_get_relation_by_id(osm, id); |
|
while(member->relation && member->relation->id != id) |
|
|
member->relation = member->relation->next; |
|
|
|
|
1655 |
if(!member->relation) { |
if(!member->relation) { |
1656 |
member->type = NODE_ID; |
member->type = NODE_ID; |
1657 |
member->id = id; |
member->id = id; |
1701 |
osm_t *osm = stack->prev->userdata[0] = |
osm_t *osm = stack->prev->userdata[0] = |
1702 |
stack->userdata[0] = g_new0(osm_t, 1); |
stack->userdata[0] = g_new0(osm_t, 1); |
1703 |
|
|
1704 |
|
osm->node_hash = g_new0(hash_table_t, 1); |
1705 |
|
osm->way_hash = g_new0(hash_table_t, 1); |
1706 |
|
|
1707 |
/* store direct pointers for faster list access */ |
/* store direct pointers for faster list access */ |
1708 |
/* (otherwise we'd have to search the end of the lists for every item */ |
/* (otherwise we'd have to search the end of the lists for every item */ |
1709 |
/* to be attached) */ |
/* to be attached) */ |
1759 |
struct timeval start; |
struct timeval start; |
1760 |
gettimeofday(&start, NULL); |
gettimeofday(&start, NULL); |
1761 |
|
|
|
|
|
1762 |
#ifdef OSM_STREAM_PARSER |
#ifdef OSM_STREAM_PARSER |
1763 |
LIBXML_TEST_VERSION; |
LIBXML_TEST_VERSION; |
1764 |
|
|
2048 |
return osm_generate_xml(osm, RELATION, relation); |
return osm_generate_xml(osm, RELATION, relation); |
2049 |
} |
} |
2050 |
|
|
2051 |
|
/* the following three functions are eating much CPU power */ |
2052 |
|
/* as they search the objects lists. Hashing is supposed to help */ |
2053 |
node_t *osm_get_node_by_id(osm_t *osm, item_id_t id) { |
node_t *osm_get_node_by_id(osm_t *osm, item_id_t id) { |
2054 |
|
if(id > 0 && osm->node_hash) { |
2055 |
|
// use hash table if present |
2056 |
|
hash_item_t *item = osm->node_hash->hash[ID2HASH(id)]; |
2057 |
|
while(item) { |
2058 |
|
if(item->data.node->id == id) |
2059 |
|
return item->data.node; |
2060 |
|
|
2061 |
|
item = item->next; |
2062 |
|
} |
2063 |
|
} |
2064 |
|
|
2065 |
|
/* use linear search if no hash tables are present or search in hash table failed */ |
2066 |
node_t *node = osm->node; |
node_t *node = osm->node; |
2067 |
while(node) { |
while(node) { |
2068 |
if(node->id == id) |
if(node->id == id) |
2069 |
return node; |
return node; |
2070 |
|
|
2071 |
node = node->next; |
node = node->next; |
2072 |
} |
} |
2073 |
|
|
2074 |
return NULL; |
return NULL; |
2075 |
} |
} |
2076 |
|
|
2077 |
way_t *osm_get_way_by_id(osm_t *osm, item_id_t id) { |
way_t *osm_get_way_by_id(osm_t *osm, item_id_t id) { |
2078 |
|
if(id > 0 && osm->way_hash) { |
2079 |
|
// use hash table if present |
2080 |
|
hash_item_t *item = osm->way_hash->hash[ID2HASH(id)]; |
2081 |
|
while(item) { |
2082 |
|
if(item->data.way->id == id) |
2083 |
|
return item->data.way; |
2084 |
|
|
2085 |
|
item = item->next; |
2086 |
|
} |
2087 |
|
} |
2088 |
|
|
2089 |
|
/* use linear search if no hash tables are present or search on hash table failed */ |
2090 |
way_t *way = osm->way; |
way_t *way = osm->way; |
2091 |
while(way) { |
while(way) { |
2092 |
if(way->id == id) |
if(way->id == id) |
2093 |
return way; |
return way; |
2094 |
|
|
2095 |
way = way->next; |
way = way->next; |
2096 |
} |
} |
2097 |
|
|
2098 |
return NULL; |
return NULL; |
2099 |
} |
} |
2100 |
|
|
2101 |
relation_t *osm_get_relation_by_id(osm_t *osm, item_id_t id) { |
relation_t *osm_get_relation_by_id(osm_t *osm, item_id_t id) { |
2102 |
|
// use linear search |
2103 |
relation_t *relation = osm->relation; |
relation_t *relation = osm->relation; |
2104 |
while(relation) { |
while(relation) { |
2105 |
if(relation->id == id) |
if(relation->id == id) |
2157 |
return 0; |
return 0; |
2158 |
} |
} |
2159 |
|
|
2160 |
|
item_id_t osm_new_relation_id(osm_t *osm) { |
2161 |
|
item_id_t id = -1; |
2162 |
|
|
2163 |
|
while(TRUE) { |
2164 |
|
gboolean found = FALSE; |
2165 |
|
relation_t *relation = osm->relation; |
2166 |
|
while(relation) { |
2167 |
|
if(relation->id == id) |
2168 |
|
found = TRUE; |
2169 |
|
|
2170 |
|
relation = relation->next; |
2171 |
|
} |
2172 |
|
|
2173 |
|
/* no such id so far -> use it */ |
2174 |
|
if(!found) return id; |
2175 |
|
|
2176 |
|
id--; |
2177 |
|
} |
2178 |
|
g_assert(0); |
2179 |
|
return 0; |
2180 |
|
} |
2181 |
|
|
2182 |
node_t *osm_node_new(osm_t *osm, gint x, gint y) { |
node_t *osm_node_new(osm_t *osm, gint x, gint y) { |
2183 |
printf("Creating new node\n"); |
printf("Creating new node\n"); |
2184 |
|
|
2215 |
*lnode = node; |
*lnode = node; |
2216 |
} |
} |
2217 |
|
|
2218 |
|
void osm_node_restore(osm_t *osm, node_t *node) { |
2219 |
|
printf("Restoring node\n"); |
2220 |
|
|
2221 |
|
/* attach to end of node list */ |
2222 |
|
node_t **lnode = &osm->node; |
2223 |
|
while(*lnode) lnode = &(*lnode)->next; |
2224 |
|
*lnode = node; |
2225 |
|
} |
2226 |
|
|
2227 |
way_t *osm_way_new(void) { |
way_t *osm_way_new(void) { |
2228 |
printf("Creating new way\n"); |
printf("Creating new way\n"); |
2229 |
|
|
2500 |
} |
} |
2501 |
} |
} |
2502 |
|
|
2503 |
|
relation_t *osm_relation_new(void) { |
2504 |
|
printf("Creating new relation\n"); |
2505 |
|
|
2506 |
|
relation_t *relation = g_new0(relation_t, 1); |
2507 |
|
relation->visible = TRUE; |
2508 |
|
relation->flags = OSM_FLAG_NEW; |
2509 |
|
relation->time = time(NULL); |
2510 |
|
|
2511 |
|
/* add created_by tag */ |
2512 |
|
relation->tag = g_new0(tag_t, 1); |
2513 |
|
relation->tag->key = g_strdup("created_by"); |
2514 |
|
relation->tag->value = g_strdup(PACKAGE " v" VERSION); |
2515 |
|
|
2516 |
|
return relation; |
2517 |
|
} |
2518 |
|
|
2519 |
|
void osm_relation_attach(osm_t *osm, relation_t *relation) { |
2520 |
|
printf("Attaching relation\n"); |
2521 |
|
|
2522 |
|
relation->id = osm_new_relation_id(osm); |
2523 |
|
relation->flags = OSM_FLAG_NEW; |
2524 |
|
|
2525 |
|
/* attach to end of relation list */ |
2526 |
|
relation_t **lrelation = &osm->relation; |
2527 |
|
while(*lrelation) lrelation = &(*lrelation)->next; |
2528 |
|
*lrelation = relation; |
2529 |
|
} |
2530 |
|
|
2531 |
|
|
2532 |
void osm_way_delete(osm_t *osm, icon_t **icon, |
void osm_way_delete(osm_t *osm, icon_t **icon, |
2533 |
way_t *way, gboolean permanently) { |
way_t *way, gboolean permanently) { |
2534 |
|
|
2667 |
|
|
2668 |
return new_tags; |
return new_tags; |
2669 |
} |
} |
2670 |
|
|
2671 |
|
/* return plain text of type */ |
2672 |
|
char *osm_type_string(type_t type) { |
2673 |
|
const struct { type_t type; char *name; } types[] = { |
2674 |
|
{ ILLEGAL, "illegal" }, |
2675 |
|
{ NODE, "node" }, |
2676 |
|
{ WAY, "way" }, |
2677 |
|
{ RELATION, "relation" }, |
2678 |
|
{ NODE_ID, "node id" }, |
2679 |
|
{ WAY_ID, "way id" }, |
2680 |
|
{ RELATION_ID, "relation id" }, |
2681 |
|
{ 0, NULL } |
2682 |
|
}; |
2683 |
|
|
2684 |
|
int i; |
2685 |
|
for(i=0;types[i].name;i++) |
2686 |
|
if(type == types[i].type) |
2687 |
|
return types[i].name; |
2688 |
|
|
2689 |
|
return NULL; |
2690 |
|
} |
2691 |
|
|
2692 |
|
char *osm_object_string(type_t type, void *object) { |
2693 |
|
char *type_str = osm_type_string(type); |
2694 |
|
|
2695 |
|
if(!object) |
2696 |
|
return g_strdup_printf("%s #<invalid>", type_str); |
2697 |
|
|
2698 |
|
switch(type) { |
2699 |
|
case ILLEGAL: |
2700 |
|
return g_strdup_printf("%s #<unspec>", type_str); |
2701 |
|
break; |
2702 |
|
case NODE: |
2703 |
|
return g_strdup_printf("%s #%ld", type_str, ((node_t*)object)->id); |
2704 |
|
break; |
2705 |
|
case WAY: |
2706 |
|
return g_strdup_printf("%s #%ld", type_str, ((way_t*)object)->id); |
2707 |
|
break; |
2708 |
|
case RELATION: |
2709 |
|
return g_strdup_printf("%s #%ld", type_str, ((relation_t*)object)->id); |
2710 |
|
break; |
2711 |
|
case NODE_ID: |
2712 |
|
case WAY_ID: |
2713 |
|
case RELATION_ID: |
2714 |
|
return g_strdup_printf("%s #%ld", type_str, *((item_id_t*)object)); |
2715 |
|
break; |
2716 |
|
} |
2717 |
|
return NULL; |
2718 |
|
} |
2719 |
|
|
2720 |
// vim:et:ts=8:sw=2:sts=2:ai |
// vim:et:ts=8:sw=2:sts=2:ai |