int output_pgsql_t::relation_delete(osmid_t osm_id) { if( !m_options.slim ) { fprintf( stderr, "Cannot apply diffs unless in slim mode\n" ); util::exit_nicely(); } pgsql_delete_relation_from_output(osm_id); return 0; }
/* This is the workhorse of pgsql_add_relation, split out because it is used as the callback for iterate relations */ int output_pgsql_t::pgsql_process_relation(osmid_t id, const memberlist_t &members, const taglist_t &tags, int exists, bool pending) { /* If the flag says this object may exist already, delete it first */ if(exists) pgsql_delete_relation_from_output(id); taglist_t outtags; if (m_tagtransform->filter_rel_tags(tags, *m_export_list.get(), outtags)) return 1; idlist_t xid2; multitaglist_t xtags2; multinodelist_t xnodes; for (memberlist_t::const_iterator it = members.begin(); it != members.end(); ++it) { /* Need to handle more than just ways... */ if (it->type == OSMTYPE_WAY) xid2.push_back(it->id); } idlist_t xid; m_mid->ways_get_list(xid2, xid, xtags2, xnodes); int polygon = 0, roads = 0; multitaglist_t xtags(xid.size(), taglist_t()); rolelist_t xrole(xid.size(), 0); for (size_t i = 0; i < xid.size(); i++) { for (size_t j = i; j < members.size(); j++) { if (members[j].id == xid[i]) { //filter the tags on this member because we got it from the middle //and since the middle is no longer tied to the output it no longer //shares any kind of tag transform and therefore all original tags //will come back and need to be filtered by individual outputs before //using these ways m_tagtransform->filter_way_tags(xtags2[i], &polygon, &roads, *m_export_list.get(), xtags[i]); //TODO: if the filter says that this member is now not interesting we //should decrement the count and remove his nodes and tags etc. for //now we'll just keep him with no tags so he will get filtered later xrole[i] = &members[j].role; break; } } } /* At some point we might want to consider storing the retrieved data in the members, rather than as separate arrays */ pgsql_out_relation(id, outtags, xnodes, xtags, xid, xrole, pending); return 0; }
int output_pgsql_t::pending_relation(osmid_t id, int exists) { // Try to fetch the relation from the DB // Note that we cannot use the global buffer here because // we cannot keep a reference to the relation and an autogrow buffer // might be relocated when more data is added. rels_buffer.clear(); if (m_mid->relations_get(id, rels_buffer)) { // If the flag says this object may exist already, delete it first. if (exists) { pgsql_delete_relation_from_output(id); } auto const &rel = rels_buffer.get<osmium::Relation>(0); return pgsql_process_relation(rel); } return 0; }
/* This is the workhorse of pgsql_add_relation, split out because it is used as the callback for iterate relations */ int output_pgsql_t::pgsql_process_relation(osmid_t id, const struct member *members, int member_count, struct keyval *tags, int exists, bool pending) { int i, j, count, count2; /* If the flag says this object may exist already, delete it first */ if(exists) pgsql_delete_relation_from_output(id); if (m_tagtransform->filter_rel_tags(tags, m_export_list.get())) { return 1; } osmid_t *xid2 = (osmid_t *)malloc( (member_count+1) * sizeof(osmid_t) ); const char **xrole = (const char **)malloc( (member_count+1) * sizeof(const char *) ); int *xcount = (int *)malloc( (member_count+1) * sizeof(int) ); keyval *xtags = new keyval[member_count+1]; struct osmNode **xnodes = (struct osmNode **)malloc( (member_count+1) * sizeof(struct osmNode*) ); count = 0; for( i=0; i<member_count; i++ ) { /* Need to handle more than just ways... */ if( members[i].type != OSMTYPE_WAY ) continue; xid2[count] = members[i].id; count++; } osmid_t *xid = (osmid_t *)malloc( sizeof(osmid_t) * (count + 1)); count2 = m_mid->ways_get_list(xid2, count, xid, xtags, xnodes, xcount); int polygon = 0, roads = 0;; for (i = 0; i < count2; i++) { for (j = i; j < member_count; j++) { if (members[j].id == xid[i]) { //filter the tags on this member because we got it from the middle //and since the middle is no longer tied to the output it no longer //shares any kind of tag transform and therefore all original tags //will come back and need to be filtered by individual outputs before //using these ways m_tagtransform->filter_way_tags(&xtags[i], &polygon, &roads, m_export_list.get()); //TODO: if the filter says that this member is now not interesting we //should decrement the count and remove his nodes and tags etc. for //now we'll just keep him with no tags so he will get filtered later break; } } xrole[i] = members[j].role; } xnodes[count2] = NULL; xcount[count2] = 0; xid[count2] = 0; xrole[count2] = NULL; /* At some point we might want to consider storing the retrieved data in the members, rather than as separate arrays */ pgsql_out_relation(id, tags, count2, xnodes, xtags, xcount, xid, xrole, pending); for( i=0; i<count2; i++ ) { xtags[i].resetList(); free( xnodes[i] ); } free(xid2); free(xid); free(xrole); free(xcount); delete [] xtags; free(xnodes); return 0; }