int output_pgsql_t::pending_way(osmid_t id, int exists) { taglist_t tags_int; nodelist_t nodes_int; // Try to fetch the way from the DB if (m_mid->ways_get(id, tags_int, nodes_int)) { /* If the flag says this object may exist already, delete it first */ if (exists) { pgsql_delete_way_from_output(id); // TODO: this now only has an effect when called from the iterate_ways // call-back, so we need some alternative way to trigger this within // osmdata_t. const idlist_t rel_ids = m_mid->relations_using_way(id); for (auto &mid: rel_ids) { rels_pending_tracker->mark(mid); } } taglist_t outtags; int polygon; int roads; if (!m_tagtransform->filter_way_tags(tags_int, &polygon, &roads, *m_export_list.get(), outtags)) { return pgsql_out_way(id, outtags, nodes_int, polygon, roads); } } return 0; }
int output_pgsql_t::pending_way(osmid_t id, int exists) { // Try to fetch the way from the DB buffer.clear(); if (m_mid->ways_get(id, buffer)) { /* If the flag says this object may exist already, delete it first */ if (exists) { pgsql_delete_way_from_output(id); // TODO: this now only has an effect when called from the iterate_ways // call-back, so we need some alternative way to trigger this within // osmdata_t. const idlist_t rel_ids = m_mid->relations_using_way(id); for (auto &mid: rel_ids) { rels_pending_tracker.mark(mid); } } taglist_t outtags; int polygon; int roads; auto &way = buffer.get<osmium::Way>(0); if (!m_tagtransform->filter_tags(way, &polygon, &roads, outtags)) { auto nnodes = m_mid->nodes_get_list(&(way.nodes())); if (nnodes > 1) { pgsql_out_way(way, &outtags, polygon, roads); return 1; } } } return 0; }
int output_pgsql_t::way_delete(osmid_t osm_id) { if( !m_options.slim ) { fprintf( stderr, "Cannot apply diffs unless in slim mode\n" ); util::exit_nicely(); } pgsql_delete_way_from_output(osm_id); return 0; }
/* COPY planet_osm (osm_id, name, place, landuse, leisure, "natural", man_made, waterway, highway, railway, amenity, tourism, learning, bu ilding, bridge, layer, way) FROM stdin; 198497 Bedford Road \N \N \N \N \N \N residential \N \N \N \N \N \N \N 0102000020E610000004000000452BF702B342D5BF1C60E63BF8DF49406B9C4D470037D5BF5471E316F3DF4940DFA815A6EF35D5BF9AE95E27F5DF4940B41EB E4C1421D5BF24D06053E7DF4940 212696 Oswald Road \N \N \N \N \N \N minor \N \N \N \N \N \N \N 0102000020E610000004000000467D923B6C22D5BFA359D93EE4DF4940B3976DA7AD11D5BF84BBB376DBDF4940997FF44D9A06D5BF4223D8B8FEDF49404D158C4AEA04D 5BF5BB39597FCDF4940 */ int output_pgsql_t::pgsql_out_way(osmid_t id, const taglist_t &tags, const nodelist_t &nodes, int exists) { int polygon = 0, roads = 0; double split_at; /* If the flag says this object may exist already, delete it first */ if (exists) { pgsql_delete_way_from_output(id); // TODO: this now only has an effect when called from the iterate_ways // call-back, so we need some alternative way to trigger this within // osmdata_t. const idlist_t rel_ids = m_mid->relations_using_way(id); for (idlist_t::const_iterator itr = rel_ids.begin(); itr != rel_ids.end(); ++itr) { rels_pending_tracker->mark(*itr); } } taglist_t outtags; if (m_tagtransform->filter_way_tags(tags, &polygon, &roads, *m_export_list.get(), outtags)) return 0; /* Split long ways after around 1 degree or 100km */ if (m_options.projection->get_proj_id() == PROJ_LATLONG) split_at = 1; else split_at = 100 * 1000; tag *areatag = 0; geometry_builder::maybe_wkts_t wkts = builder.get_wkt_split(nodes, polygon, split_at); for(geometry_builder::wkt_itr wkt = wkts->begin(); wkt != wkts->end(); ++wkt) { /* FIXME: there should be a better way to detect polygons */ if (boost::starts_with(wkt->geom, "POLYGON") || boost::starts_with(wkt->geom, "MULTIPOLYGON")) { expire->from_nodes_poly(nodes, id); if ((wkt->area > 0.0) && m_enable_way_area) { char tmp[32]; snprintf(tmp, sizeof(tmp), "%g", wkt->area); if (!areatag) { outtags.push_dedupe(tag("way_area", tmp)); areatag = outtags.find("way_area"); } else areatag->value = tmp; } m_tables[t_poly]->write_wkt(id, outtags, wkt->geom.c_str()); } else { expire->from_nodes_line(nodes); m_tables[t_line]->write_wkt(id, outtags, wkt->geom.c_str()); if (roads) m_tables[t_roads]->write_wkt(id, outtags, wkt->geom.c_str()); } } return 0; }
int output_pgsql_t::pgsql_out_relation(osmid_t id, const taglist_t &rel_tags, const multinodelist_t &xnodes, const multitaglist_t & xtags, const idlist_t &xid, const rolelist_t &xrole, bool pending) { if (xnodes.empty()) return 0; int roads = 0; int make_polygon = 0; int make_boundary = 0; double split_at; std::vector<int> members_superseeded(xnodes.size(), 0); taglist_t outtags; //if its a route relation make_boundary and make_polygon will be false otherwise one or the other will be true if (m_tagtransform->filter_rel_member_tags(rel_tags, xtags, xrole, &(members_superseeded[0]), &make_boundary, &make_polygon, &roads, *m_export_list.get(), outtags)) { return 0; } /* Split long linear ways after around 1 degree or 100km (polygons not effected) */ if (m_options.projection->get_proj_id() == PROJ_LATLONG) split_at = 1; else split_at = 100 * 1000; //this will either make lines or polygons (unless the lines arent a ring or are less than 3 pts) depending on the tag transform above //TODO: pick one or the other based on which we expect to care about auto wkbs = builder.build_both(xnodes, make_polygon, m_options.enable_multi, split_at, id); if (wkbs.empty()) { return 0; } tag_t *areatag = 0; char tmp[32]; for (const auto& wkb: wkbs) { expire->from_wkb(wkb.geom.c_str(), -id); /* FIXME: there should be a better way to detect polygons */ if (wkb.is_polygon()) { if ((wkb.area > 0.0) && m_enable_way_area) { snprintf(tmp, sizeof(tmp), "%g", wkb.area); if (!areatag) { outtags.push_dedupe(tag_t("way_area", tmp)); areatag = outtags.find("way_area"); } } m_tables[t_poly]->write_row(-id, outtags, wkb.geom); } else { m_tables[t_line]->write_row(-id, outtags, wkb.geom); if (roads) m_tables[t_roads]->write_row(-id, outtags, wkb.geom); } } /* Tagtransform will have marked those member ways of the relation that * have fully been dealt with as part of the multi-polygon entry. * Set them in the database as done and delete their entry to not * have duplicates */ //dont do this when working with pending relations as its not needed if (make_polygon) { for (size_t i=0; i < xid.size(); i++) { if (members_superseeded[i]) { pgsql_delete_way_from_output(xid[i]); if(!pending) ways_done_tracker->mark(xid[i]); } } } // If the tag transform said the polygon looked like a boundary we want to make that as well // If we are making a boundary then also try adding any relations which form complete rings // The linear variants will have already been processed above if (make_boundary) { wkbs = builder.build_polygons(xnodes, m_options.enable_multi, id); for (const auto& wkb: wkbs) { expire->from_wkb(wkb.geom.c_str(), -id); if ((wkb.area > 0.0) && m_enable_way_area) { snprintf(tmp, sizeof(tmp), "%g", wkb.area); if (!areatag) { outtags.push_dedupe(tag_t("way_area", tmp)); areatag = outtags.find("way_area"); } } m_tables[t_poly]->write_row(-id, outtags, wkb.geom); } } return 0; }
int output_pgsql_t::pgsql_out_relation(osmid_t id, struct keyval *rel_tags, int member_count, const struct osmNode * const *xnodes, struct keyval *xtags, const int *xcount, const osmid_t *xid, const char * const *xrole, bool pending) { if (member_count == 0) return 0; int roads = 0; int make_polygon = 0; int make_boundary = 0; int * members_superseeded; double split_at; members_superseeded = (int *)calloc(sizeof(int), member_count); //if its a route relation make_boundary and make_polygon will be false otherwise one or the other will be true if (m_tagtransform->filter_rel_member_tags(rel_tags, member_count, xtags, xrole, members_superseeded, &make_boundary, &make_polygon, &roads, m_export_list.get())) { free(members_superseeded); return 0; } /* Split long linear ways after around 1 degree or 100km (polygons not effected) */ if (m_options.projection->get_proj_id() == PROJ_LATLONG) split_at = 1; else split_at = 100 * 1000; //this will either make lines or polygons (unless the lines arent a ring or are less than 3 pts) depending on the tag transform above //TODO: pick one or the other based on which we expect to care about geometry_builder::maybe_wkts_t wkts = builder.build_both(xnodes, xcount, make_polygon, m_options.enable_multi, split_at, id); if (!wkts->size()) { free(members_superseeded); return 0; } for(geometry_builder::wkt_itr wkt = wkts->begin(); wkt != wkts->end(); ++wkt) { expire->from_wkt(wkt->geom.c_str(), -id); /* FIXME: there should be a better way to detect polygons */ if (boost::starts_with(wkt->geom, "POLYGON") || boost::starts_with(wkt->geom, "MULTIPOLYGON")) { if ((wkt->area > 0.0) && m_enable_way_area) { char tmp[32]; snprintf(tmp, sizeof(tmp), "%g", wkt->area); rel_tags->addItem("way_area", tmp, false); } m_tables[t_poly]->write_wkt(-id, rel_tags, wkt->geom.c_str()); } else { m_tables[t_line]->write_wkt(-id, rel_tags, wkt->geom.c_str()); if (roads) m_tables[t_roads]->write_wkt(-id, rel_tags, wkt->geom.c_str()); } } /* Tagtransform will have marked those member ways of the relation that * have fully been dealt with as part of the multi-polygon entry. * Set them in the database as done and delete their entry to not * have duplicates */ //dont do this when working with pending relations as its not needed if (make_polygon) { for (int i=0; xcount[i]; i++) { if (members_superseeded[i]) { pgsql_delete_way_from_output(xid[i]); if(!pending) ways_done_tracker->mark(xid[i]); } } } free(members_superseeded); // If the tag transform said the polygon looked like a boundary we want to make that as well // If we are making a boundary then also try adding any relations which form complete rings // The linear variants will have already been processed above if (make_boundary) { wkts = builder.build_polygons(xnodes, xcount, m_options.enable_multi, id); for(geometry_builder::wkt_itr wkt = wkts->begin(); wkt != wkts->end(); ++wkt) { expire->from_wkt(wkt->geom.c_str(), -id); if ((wkt->area > 0.0) && m_enable_way_area) { char tmp[32]; snprintf(tmp, sizeof(tmp), "%g", wkt->area); rel_tags->addItem("way_area", tmp, false); } m_tables[t_poly]->write_wkt(-id, rel_tags, wkt->geom.c_str()); } } return 0; }