// - walk over all relations-versions
    //   - walk over all relations-nodes
    //     - Adds the nodes and ways that aren't in node-tracker to a vector
    //     - if node or way is in the box hit becames true
    //   - if hit is true and the vector is not empty (it means their are nodes or ways that belong to a relation that has at least one node or way inside the box)
    //     - Records the id of node or way to outside_node_tracker or outside_way_tracker
    void relation(const osmium::Relation& relation) {
	
    	bool hit = false;

        if (debug) {
            std::cerr << "cut_administrative relation " << relation.id() << " v" << relation.version() << "\n";
        }
    	
        std::vector<const osmium::RelationMember*> members;
        std::vector<const osmium::TagList*> tags;

        for (auto& tag : relation.tags()) {
            if (strcmp(tag.key(), "boundary") == 0 && strcmp(tag.value(), "administrative") == 0)
                hit = true;
        }

    	for (const auto& extract : info->extracts) {
            if (hit){
                if(!extract->relation_tracker.get(relation.id())){
                    extract->relation_tracker.set(relation.id());
                }
                //Add only the nodes and ways that were not yet in the respective trackers if hit is true
                for (const auto& member : relation.members()) {
                    if (member.type() == osmium::item_type::way && !extract->way_tracker.get(member.ref())){
                            extract->way_tracker.set(member.ref());
                    } 
                }
            }
        }
    }
示例#2
0
 void relation(const osmium::Relation& relation) {
     if (m_max_relation_id == relation.id()) {
         throw out_of_order_error{"Relation ID twice in input. Maybe you are using a history or change file?", relation.id()};
     }
     if (id_order{}(relation.id(), m_max_relation_id)) {
         throw out_of_order_error{"Relation IDs out of order.", relation.id()};
     }
     m_max_relation_id = relation.id();
 }
示例#3
0
    // - walk over all relation-versions
    //   - walk over all bboxes
    //     - if the relation-id is recorded in the bboxes relation-tracker
    //       - send the relation to the bboxes writer
    void relation(const osmium::Relation& relation) {
        if (debug) {
            std::cerr << "softcut relation " << relation.id() << " v" << relation.version() << "\n";
        }

        for (const auto& extract : info->extracts) {
            if (extract->relation_tracker.get(relation.id())) {
                extract->write(relation);
            }
        }
    }
示例#4
0
void parse_osmium_t::relation(osmium::Relation& rel)
{
    if (rel.deleted()) {
        m_data->relation_delete(rel.id());
    } else {
        if (m_append) {
            m_data->relation_modify(rel);
        } else {
            m_data->relation_add(rel);
        }
    }
    m_stats.add_rel(rel.id());
}
示例#5
0
int osmdata_t::relation_modify(osmium::Relation const &rel)
{
    slim_middle_t *slim = dynamic_cast<slim_middle_t *>(mid.get());

    slim->relations_delete(rel.id());
    slim->relations_set(rel);

    int status = 0;
    for (auto& out: outs) {
        status |= out->relation_modify(rel);
    }

    slim->relation_changed(rel.id());

    return status;
}
    void relation(const osmium::Relation& relation) {
        m_check_order.relation(relation);

        if (m_relation_count == 0) {
            m_progress_bar.remove();
            m_vout << "Reading relations...\n";
        }
        ++m_relation_count;

        if (m_check_relations) {
            set(osmium::item_type::relation, relation.id());
            for (const auto& member : relation.members()) {
                switch (member.type()) {
                    case osmium::item_type::node:
                        if (!get(osmium::item_type::node, member.ref())) {
                            ++m_missing_nodes_in_relations;
                            set(osmium::item_type::node, member.ref());
                            if (m_show_ids) {
                                std::cout << "n" << member.ref() << " in r" << relation.id() << "\n";
                            }
                        }
                        break;
                    case osmium::item_type::way:
                        if (!get(osmium::item_type::way, member.ref())) {
                            ++m_missing_ways_in_relations;
                            set(osmium::item_type::way, member.ref());
                            if (m_show_ids) {
                                std::cout << "w" << member.ref() << " in r" << relation.id() << "\n";
                            }
                        }
                        break;
                    case osmium::item_type::relation:
                        if (member.ref() > relation.id() || !get(osmium::item_type::relation, member.ref())) {
                            m_relation_refs.emplace_back(member.ref(), relation.id());
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    }
示例#7
0
int output_pgsql_t::relation_modify(osmium::Relation const &rel)
{
    if( !m_options.slim )
    {
        fprintf( stderr, "Cannot apply diffs unless in slim mode\n" );
        util::exit_nicely();
    }
    relation_delete(rel.id());
    relation_add(rel);
    return 0;
}
示例#8
0
    // - walk over all relation-versions
    //   - walk over all bboxes
    //     - walk over all relation-members
    //       - if the relation-member is recorded in the bboxes node- or way-tracker
    //         - record its id in the bboxes relation-tracker
    void relation(const osmium::Relation& relation) {
        if (first_relation) {
            write_way_extra_nodes();
            first_relation = false;
        }

        if (debug) {
            std::cerr << "softcut relation " << relation.id() << " v" << relation.version() << "\n";
        }

        for (const auto& extract : info->extracts) {
            bool hit = false;

            for (const auto& member : relation.members()) {

                if (!hit && (
                    (member.type() == osmium::item_type::node && extract->node_tracker.get(member.ref())) ||
                    (member.type() == osmium::item_type::way && extract->way_tracker.get(member.ref())) ||
                    (member.type() == osmium::item_type::relation && extract->relation_tracker.get(member.ref()))
                )) {

                    if (debug) std::cerr << "relation has a member (" << member.type() << " " << member.ref() << ") inside extract, recording in relation_tracker\n";
                    hit = true;

                    extract->relation_tracker.set(relation.id());
                }

                if (member.type() == osmium::item_type::relation) {
                    if (debug) {
                        std::cerr << "recording cascading-pair: " << member.ref() << " -> " << relation.id() << "\n";
                    }
                    info->cascading_relations_tracker.insert(std::make_pair(member.ref(), relation.id()));
                }
            }

            if (hit) {
                cascading_relations(extract, relation.id());
            }
        }
    }
 void relation(const osmium::Relation& rel) {
     ++rels;
     if (!matches_user_filter(rel)) return;
     ++urels;
     if (rel.visible()==false) {
         m_relfile <<
             rel.id() << "\t" <<
             rel.version() << "\t" <<
             rel.changeset() << "\t" <<
             rel.timestamp().to_iso() << "\t" <<
             rel.uid() << std::endl;
     }
 }
示例#10
0
            /**
             * Assemble an area from the given relation and its members.
             * The resulting area is put into the out_buffer.
             *
             * @returns false if there was some kind of error building the
             *          area(s), true otherwise.
             */
            bool operator()(const osmium::Relation& relation, const std::vector<const osmium::Way*>& members, osmium::memory::Buffer& out_buffer) {
                if (!config().create_new_style_polygons) {
                    return true;
                }

                assert(relation.cmembers().size() >= members.size());

                if (config().problem_reporter) {
                    config().problem_reporter->set_object(osmium::item_type::relation, relation.id());
                }

                if (relation.members().empty()) {
                    ++stats().no_way_in_mp_relation;
                    return false;
                }

                ++stats().from_relations;
                stats().invalid_locations = segment_list().extract_segments_from_ways(config().problem_reporter,
                                                                                      stats().duplicate_nodes,
                                                                                      stats().duplicate_ways,
                                                                                      relation,
                                                                                      members);
                if (!config().ignore_invalid_locations && stats().invalid_locations > 0) {
                    return false;
                }
                stats().member_ways = members.size();

                if (stats().member_ways == 1) {
                    ++stats().single_way_in_mp_relation;
                }

                if (config().debug_level > 0) {
                    std::cerr << "\nAssembling relation " << relation.id() << " containing " << members.size() << " way members with " << segment_list().size() << " nodes\n";
                }

                // Now create the Area object and add the attributes and tags
                // from the relation.
                bool okay = create_area(out_buffer, relation, members);
                if (okay) {
                    out_buffer.commit();
                } else {
                    out_buffer.rollback();
                }

                return okay;
            }
示例#11
0
void middle_pgsql_t::relations_set(osmium::Relation const &rel)
{
    idlist_t parts[3];

    for (auto const &m : rel.members()) {
        parts[osmium::item_type_to_nwr_index(m.type())].push_back(m.ref());
    }

    copy_buffer.reserve(rel.members().byte_size() * 2 + rel.tags().byte_size() + 128);

    // Params: id, way_off, rel_off, parts, members, tags */
    const char *paramValues[6] = { copy_buffer.c_str(), };
    bool copy = rel_table->copyMode;
    char delim = copy ? '\t' : '\0';

    copy_buffer = std::to_string(rel.id());
    copy_buffer+= delim;

    paramValues[1] = paramValues[0] + copy_buffer.size();
    copy_buffer += std::to_string(parts[0].size());
    copy_buffer+= delim;

    paramValues[2] = paramValues[0] + copy_buffer.size();
    copy_buffer += std::to_string(parts[0].size() + parts[1].size());
    copy_buffer+= delim;

    paramValues[3] = paramValues[0] + copy_buffer.size();
    if (rel.members().empty()) {
        copy_buffer += "{}";
    } else {
        copy_buffer += "{";
        for (int i = 0; i < 3; ++i) {
            for (auto it : parts[i]) {
                copy_buffer += std::to_string(it);
                copy_buffer += ',';
            }
        }
        copy_buffer[copy_buffer.size() - 1] = '}';
    }
    copy_buffer+= delim;

    if (rel.members().empty()) {
        paramValues[4] = nullptr;
        copy_buffer += "\\N";
    } else {
        paramValues[4] = paramValues[0] + copy_buffer.size();
        copy_buffer += "{";
        for (auto const &m : rel.members()) {
            copy_buffer += '"';
            copy_buffer += osmium::item_type_to_char(m.type());
            copy_buffer += std::to_string(m.ref());
            copy_buffer += "\",\"";
            buffer_store_string(m.role(), copy);
            copy_buffer += "\",";
        }
        copy_buffer[copy_buffer.size() - 1] = '}';
    }
    copy_buffer+= delim;

    if (rel.tags().empty() && !out_options->extra_attributes) {
        paramValues[5] = nullptr;
        copy_buffer += "\\N";
    } else {
        paramValues[5] = paramValues[0] + copy_buffer.size();
        buffer_store_tags(rel, out_options->extra_attributes, copy);
    }

    if (copy) {
        copy_buffer+= '\n';
        pgsql_CopyData(__FUNCTION__, rel_table->sql_conn, copy_buffer);
    } else {
        buffer_correct_params(paramValues, 6);
        pgsql_execPrepared(rel_table->sql_conn, "insert_rel", 6,
                           (const char * const *)paramValues, PGRES_COMMAND_OK);
    }
}
示例#12
0
void middle_ram_t::relations_set(osmium::Relation const &rel)
{
    rels.set(rel.id(), new ramRel(rel, out_options->extra_attributes));
}
示例#13
0
 void relation(const osmium::Relation& relation) {
     if (m_max_relation_id >= relation.id()) {
         throw std::runtime_error("Relation IDs out of order.");
     }
     m_max_relation_id = relation.id();
 }
示例#14
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(osmium::Relation const &rel)
{
    taglist_t prefiltered_tags;
    if (m_tagtransform->filter_tags(rel, nullptr, nullptr, prefiltered_tags)) {
        return 1;
    }

    idlist_t xid2;
    for (auto const &m : rel.members()) {
        /* Need to handle more than just ways... */
        if (m.type() == osmium::item_type::way) {
            xid2.push_back(m.ref());
        }
    }

    buffer.clear();
    rolelist_t xrole;
    auto num_ways = m_mid->rel_way_members_get(rel, &xrole, buffer);

    if (num_ways == 0)
        return 0;

  int roads = 0;
  int make_polygon = 0;
  int make_boundary = 0;
  taglist_t outtags;

  // If it's 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(prefiltered_tags, buffer, xrole,
                                             &make_boundary, &make_polygon,
                                             &roads, outtags)) {
      return 0;
  }

  for (auto &w : buffer.select<osmium::Way>()) {
      m_mid->nodes_get_list(&(w.nodes()));
  }

  // linear features and boundaries
  // Needs to be done before the polygon treatment below because
  // for boundaries the way_area tag may be added.
  if (!make_polygon) {
      double const split_at = m_options.projection->target_latlon() ? 1 : 100 * 1000;
      auto wkbs = m_builder.get_wkb_multiline(buffer, split_at);
      for (auto const &wkb : wkbs) {
          expire.from_wkb(wkb.c_str(), -rel.id());
          m_tables[t_line]->write_row(-rel.id(), outtags, wkb);
          if (roads)
              m_tables[t_roads]->write_row(-rel.id(), outtags, wkb);
      }
  }

  // multipolygons and boundaries
  if (make_boundary || make_polygon) {
      auto wkbs = m_builder.get_wkb_multipolygon(rel, buffer);

      char tmp[32];
      for (auto const &wkb : wkbs) {
          expire.from_wkb(wkb.c_str(), -rel.id());
          if (m_enable_way_area) {
              auto const area =
                  m_options.reproject_area
                      ? ewkb::parser_t(wkb).get_area<reprojection>(
                            m_options.projection.get())
                      : ewkb::parser_t(wkb)
                            .get_area<osmium::geom::IdentityProjection>();
              snprintf(tmp, sizeof(tmp), "%g", area);
              outtags.push_override(tag_t("way_area", tmp));
          }
          m_tables[t_poly]->write_row(-rel.id(), outtags, wkb);
      }
  }

  return 0;
}
示例#15
0
 int relation_add(osmium::Relation const &r) override {
     assert(r.id() > 0);
     ++rel.added;
     return 0;
 }
示例#16
0
 void relations(const osmium::Relation& relation) {
     id_check(relation.id(), 900, 999);
     --m_num_relations;
 }