예제 #1
0
bool middle_pgsql_t::relations_get(osmid_t id, memberlist_t &members, taglist_t &tags) const
{
    char tmp[16];
    char const *paramValues[1];
    PGconn *sql_conn = rel_table->sql_conn;
    taglist_t member_temp;

    // Make sure we're out of copy mode */
    pgsql_endCopy( rel_table );

    snprintf(tmp, sizeof(tmp), "%" PRIdOSMID, id);
    paramValues[0] = tmp;

    PGresult *res = pgsql_execPrepared(sql_conn, "get_rel", 1, paramValues, PGRES_TUPLES_OK);
    // Fields are: members, tags, member_count */

    if (PQntuples(res) != 1) {
        PQclear(res);
        return false;
    }

    pgsql_parse_tags(PQgetvalue(res, 0, 1), tags);
    pgsql_parse_tags(PQgetvalue(res, 0, 0), member_temp);

    if (member_temp.size() != strtoul(PQgetvalue(res, 0, 2), nullptr, 10)) {
        fprintf(stderr, "Unexpected member_count reading relation %" PRIdOSMID "\n", id);
        util::exit_nicely();
    }

    PQclear(res);

    for (taglist_t::const_iterator it = member_temp.begin(); it != member_temp.end(); ++it) {
        char tag = it->key[0];
        OsmType type = (tag == 'n')?OSMTYPE_NODE:(tag == 'w')?OSMTYPE_WAY:(tag == 'r')?OSMTYPE_RELATION:((OsmType)-1);
        members.push_back(member(type,
                                 strtoosmid(it->key.c_str()+1, nullptr, 10 ),
                                 it->value));
    }
    return true;
}
int output_multi_t::relation_add(osmid_t id, const memberlist_t &members, const taglist_t &tags) {
    if (m_processor->interests(geometry_processor::interest_relation) && !members.empty()) {
        return process_relation(id, members, tags, 0);
    }
    return 0;
}
예제 #3
0
void middle_pgsql_t::relations_set(osmid_t id, const memberlist_t &members, const taglist_t &tags)
{
    taglist_t member_list;
    char buf[64];

    idlist_t all_parts, node_parts, way_parts, rel_parts;
    all_parts.reserve(members.size());
    node_parts.reserve(members.size());
    way_parts.reserve(members.size());
    rel_parts.reserve(members.size());

    for (memberlist_t::const_iterator it = members.begin(); it != members.end(); ++it) {
        char type = 0;
        switch (it->type)
        {
            case OSMTYPE_NODE:     node_parts.push_back(it->id); type = 'n'; break;
            case OSMTYPE_WAY:      way_parts.push_back(it->id); type = 'w'; break;
            case OSMTYPE_RELATION: rel_parts.push_back(it->id); type = 'r'; break;
            default:
                fprintf(stderr, "Internal error: Unknown member type %d\n", it->type);
                util::exit_nicely();
        }
        sprintf( buf, "%c%" PRIdOSMID, type, it->id );
        member_list.push_back(tag_t(buf, it->role));
    }

    all_parts.insert(all_parts.end(), node_parts.begin(), node_parts.end());
    all_parts.insert(all_parts.end(), way_parts.begin(), way_parts.end());
    all_parts.insert(all_parts.end(), rel_parts.begin(), rel_parts.end());

    copy_buffer.reserve(all_parts.size() * 10 + member_list.size() * 24
                        + tags.size() * 24 + 64);

    // 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(id);
    copy_buffer+= delim;

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

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

    paramValues[3] = paramValues[0] + copy_buffer.size();
    buffer_store_nodes(all_parts);
    copy_buffer+= delim;

    if (member_list.size() == 0) {
        paramValues[4] = nullptr;
        copy_buffer += "\\N";
    } else {
        paramValues[4] = paramValues[0] + copy_buffer.size();
        buffer_store_tags(member_list, copy);
    }
    copy_buffer+= delim;

    if (tags.size() == 0) {
        paramValues[5] = nullptr;
        copy_buffer += "\\N";
    } else {
        paramValues[5] = paramValues[0] + copy_buffer.size();
        buffer_store_tags(tags, 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);
    }
}
예제 #4
0
int output_gazetteer_t::process_relation(osmid_t id, const memberlist_t &members,
                                         const taglist_t &tags)
{
    const std::string *type = tags.get("type");
    if (!type) {
        delete_unused_full('R', id);
        return 0;
    }

    int cmp_waterway = type->compare("waterway");

    if (*type == "associatedStreet"
            || !(*type == "boundary" || *type == "multipolygon" || !cmp_waterway)) {
        delete_unused_full('R', id);
        return 0;
    }

    places.process_tags(tags);

    if (m_options.append)
        delete_unused_classes('R', id);

    /* Are we interested in this item? */
    if (!places.has_data())
        return 0;

    /* get the boundary path (ways) */
    idlist_t xid2;
    for (memberlist_t::const_iterator it = members.begin(); it != members.end(); ++it) {
        /* only interested in ways */
        if (it->type == OSMTYPE_WAY)
            xid2.push_back(it->id);
    }

    if (xid2.empty()) {
        if (m_options.append)
            delete_unused_full('R', id);

        return 0;
    }

    multitaglist_t xtags;
    multinodelist_t xnodes;
    idlist_t xid;
    m_mid->ways_get_list(xid2, xid, xtags, xnodes);

    if (cmp_waterway) {
        geometry_builder::maybe_wkts_t wkts = builder.build_both(xnodes, 1, 1, 1000000, id);
        for (const auto& wkt: *wkts) {
            if (boost::starts_with(wkt.geom,  "POLYGON")
                    || boost::starts_with(wkt.geom,  "MULTIPOLYGON")) {
                places.copy_out('R', id, wkt.geom, buffer);
                flush_place_buffer();
            } else {
                /* add_polygon_error('R', id, "boundary", "adminitrative", &names, countrycode, wkt); */
            }
        }
    } else {
        /* waterways result in multilinestrings */
        geometry_builder::maybe_wkt_t wkt = builder.build_multilines(xnodes, id);
        if ((wkt->geom).length() > 0) {
            places.copy_out('R', id, wkt->geom, buffer);
            flush_place_buffer();
        }
    }

    return 0;
}
예제 #5
0
void middle_pgsql_t::relations_set(osmid_t id, const memberlist_t &members, const taglist_t &tags)
{
    // Params: id, way_off, rel_off, parts, members, tags */
    const char *paramValues[6];
    char *buffer;
    taglist_t member_list;
    char buf[64];

    idlist_t all_parts, node_parts, way_parts, rel_parts;
    all_parts.reserve(members.size());
    node_parts.reserve(members.size());
    way_parts.reserve(members.size());
    rel_parts.reserve(members.size());

    for (memberlist_t::const_iterator it = members.begin(); it != members.end(); ++it) {
        char type = 0;
        switch (it->type)
        {
        case OSMTYPE_NODE:
            node_parts.push_back(it->id);
            type = 'n';
            break;
        case OSMTYPE_WAY:
            way_parts.push_back(it->id);
            type = 'w';
            break;
        case OSMTYPE_RELATION:
            rel_parts.push_back(it->id);
            type = 'r';
            break;
        default:
            fprintf(stderr, "Internal error: Unknown member type %d\n", it->type);
            util::exit_nicely();
        }
        sprintf( buf, "%c%" PRIdOSMID, type, it->id );
        member_list.push_back(tag(buf, it->role));
    }

    all_parts.insert(all_parts.end(), node_parts.begin(), node_parts.end());
    all_parts.insert(all_parts.end(), way_parts.begin(), way_parts.end());
    all_parts.insert(all_parts.end(), rel_parts.begin(), rel_parts.end());

    if (rel_table->copyMode)
    {
        char *tag_buf = strdup(pgsql_store_tags(tags,1));
        const char *member_buf = pgsql_store_tags(member_list,1);
        char *parts_buf = pgsql_store_nodes(all_parts);
        int length = strlen(member_buf) + strlen(tag_buf) + strlen(parts_buf) + 64;
        buffer = (char *)alloca(length);
        if (snprintf( buffer, length, "%" PRIdOSMID "\t%zu\t%zu\t%s\t%s\t%s\n",
                      id, node_parts.size(), node_parts.size() + way_parts.size(),
                      parts_buf, member_buf, tag_buf ) > (length-10)) {
            throw std::runtime_error((boost::format("Buffer overflow relation id %1%") % id).str());
        }
        free(tag_buf);
        pgsql_CopyData(__FUNCTION__, rel_table->sql_conn, buffer);
    } else {
        buffer = (char *)alloca(64);
        char *ptr = buffer;
        paramValues[0] = ptr;
        ptr += sprintf(ptr, "%" PRIdOSMID, id ) + 1;
        paramValues[1] = ptr;
        ptr += sprintf(ptr, "%zu", node_parts.size() ) + 1;
        paramValues[2] = ptr;
        sprintf( ptr, "%zu", node_parts.size() + way_parts.size() );
        paramValues[3] = pgsql_store_nodes(all_parts);
        paramValues[4] = pgsql_store_tags(member_list,0);
        if (paramValues[4]) {
            paramValues[4] = strdup(paramValues[4]);
        }
        paramValues[5] = pgsql_store_tags(tags,0);
        pgsql_execPrepared(rel_table->sql_conn, "insert_rel", 6, (const char * const *)paramValues, PGRES_COMMAND_OK);
        if (paramValues[4]) {
            free((void *)paramValues[4]);
        }
    }
}