int output_multi_t::reprocess_way(osmid_t id, const nodelist_t &nodes, const taglist_t &tags, bool exists) { //if the way could exist already we have to make the relation pending and reprocess it later //but only if we actually care about relations if(m_processor->interests(geometry_processor::interest_relation) && exists) { way_delete(id); const std::vector<osmid_t> rel_ids = m_mid->relations_using_way(id); for (std::vector<osmid_t>::const_iterator itr = rel_ids.begin(); itr != rel_ids.end(); ++itr) { rels_pending_tracker->mark(*itr); } } //check if we are keeping this way int polygon = 0, roads = 0; taglist_t outtags; unsigned int filter = m_tagtransform->filter_way_tags(tags, &polygon, &roads, *m_export_list.get(), outtags, true); if (!filter) { //grab its geom geometry_builder::maybe_wkt_t wkt = m_processor->process_way(nodes); if (wkt) { //TODO: need to know if we care about polygons or lines for this output //the difference only being that if its a really large bbox for the poly //it downgrades to just invalidating the line/perimeter anyway if(boost::starts_with(wkt->geom, "POLYGON") || boost::starts_with(wkt->geom, "MULTIPOLYGON")) m_expire->from_nodes_poly(nodes, id); else m_expire->from_nodes_line(nodes); copy_to_table(id, wkt->geom.c_str(), outtags); } } return 0; }
int output_multi_t::process_way(osmid_t id, const idlist_t &nodes, const taglist_t &tags) { //check if we are keeping this way int polygon = 0, roads = 0; taglist_t outtags; unsigned filter = m_tagtransform->filter_way_tags(tags, &polygon, &roads, *m_export_list.get(), outtags, true); if (!filter) { //get the geom from the middle if(m_way_helper.set(nodes, m_mid) < 1) return 0; //grab its geom geometry_builder::maybe_wkt_t wkt = m_processor->process_way(m_way_helper.node_cache); if (wkt) { //if we are also interested in relations we need to mark //this way pending just in case it shows up in one if (m_processor->interests(geometry_processor::interest_relation)) { ways_pending_tracker->mark(id); }//we aren't interested in relations so if it comes in on a relation later we wont keep it else { //TODO: need to know if we care about polygons or lines for this output //the difference only being that if its a really large bbox for the poly //it downgrades to just invalidating the line/perimeter anyway if(boost::starts_with(wkt->geom, "POLYGON") || boost::starts_with(wkt->geom, "MULTIPOLYGON")) m_expire->from_nodes_poly(m_way_helper.node_cache, id); else m_expire->from_nodes_line(m_way_helper.node_cache); copy_to_table(id, wkt->geom.c_str(), outtags); } } } return 0; }
int output_multi_t::process_node(osmid_t id, double lat, double lon, struct keyval *tags) { //check if we are keeping this node unsigned int filter = m_tagtransform->filter_node_tags(tags, m_export_list.get(), true); if (!filter) { //grab its geom geometry_builder::maybe_wkt_t wkt = m_processor->process_node(lat, lon); if (wkt) { m_expire->from_bbox(lon, lat, lon, lat); copy_to_table(id, wkt->geom.c_str(), tags); } } return 0; }
int output_multi_t::process_relation(osmid_t id, const memberlist_t &members, const taglist_t &tags, bool exists, bool pending) { //if it may exist already, delete it first if(exists) relation_delete(id); //does this relation have anything interesting to us taglist_t rel_outtags; unsigned filter = m_tagtransform->filter_rel_tags(tags, *m_export_list.get(), rel_outtags, true); if (!filter) { //TODO: move this into geometry processor, figure a way to come back for tag transform //grab ways/nodes of the members in the relation, bail if none were used if(m_relation_helper.set(&members, (middle_t*)m_mid) < 1) return 0; //filter the tags on each member because we got them 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 has all original tags //so we filter here because each individual outputs cares about different tags int polygon, roads; multitaglist_t filtered(m_relation_helper.tags.size(), taglist_t()); for(size_t i = 0; i < m_relation_helper.tags.size(); ++i) { m_tagtransform->filter_way_tags(m_relation_helper.tags[i], &polygon, &roads, *m_export_list.get(), filtered[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 } //do the members of this relation have anything interesting to us //NOTE: make_polygon is preset here this is to force the tag matching/superseeded stuff //normally this wouldnt work but we tell the tag transform to allow typeless relations //this is needed because the type can get stripped off by the rel_tag filter above //if the export list did not include the type tag. //TODO: find a less hacky way to do the matching/superseeded and tag copying stuff without //all this trickery int make_boundary, make_polygon = 1; taglist_t outtags; filter = m_tagtransform->filter_rel_member_tags(rel_outtags, filtered, m_relation_helper.roles, &m_relation_helper.superseeded.front(), &make_boundary, &make_polygon, &roads, *m_export_list.get(), outtags, true); if (!filter) { geometry_builder::maybe_wkts_t wkts = m_processor->process_relation(m_relation_helper.nodes); if (wkts) { for(geometry_builder::wkt_itr wkt = wkts->begin(); wkt != wkts->end(); ++wkt) { //TODO: we actually have the nodes in the m_relation_helper and could use them //instead of having to reparse the wkt in the expiry code m_expire->from_wkt(wkt->geom.c_str(), -id); //what part of the code relies on relation members getting negative ids? copy_to_table(-id, wkt->geom.c_str(), outtags); } } //TODO: should this loop be inside the if above just in case? //take a look at each member to see if its superseeded (tags on it matched the tags on the relation) for(size_t i = 0; i < m_relation_helper.ways.size(); ++i) { //tags matched so we are keeping this one with this relation if (m_relation_helper.superseeded[i]) { //just in case it wasnt previously with this relation we get rid of them way_delete(m_relation_helper.ways[i]); //the other option is that we marked them pending in the way processing so here we mark them //done so when we go back over the pendings we can just skip it because its in the done list //TODO: dont do this when working with pending relations to avoid thread races if(!pending) ways_done_tracker->mark(m_relation_helper.ways[i]); } } } } return 0; }